Skip to content

Commit

Permalink
Improvement default value handling (#107)
Browse files Browse the repository at this point in the history
  • Loading branch information
shibayan authored Feb 17, 2021
1 parent 1fea914 commit 030bb9a
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 18 deletions.
2 changes: 1 addition & 1 deletion Sharprompt/Forms/FormRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private void ClearAll()
{
var bottom = _screenBuffer.CursorBottom;

for (int i = 0; i < _screenBuffer.LineCount; i++)
for (var i = 0; i < _screenBuffer.LineCount; i++)
{
ConsoleDriver.ClearLine(bottom - i);
}
Expand Down
10 changes: 5 additions & 5 deletions Sharprompt/Forms/Input.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ namespace Sharprompt.Forms
{
internal class Input<T> : FormBase<T>
{
public Input(string message, object defaultValue, IList<Func<object, ValidationResult>> validators)
public Input(string message, Optional<T> defaultValue, IList<Func<object, ValidationResult>> validators)
{
_message = message;
_defaultValue = defaultValue;
_validators = validators;
}

private readonly string _message;
private readonly object _defaultValue;
private readonly Optional<T> _defaultValue;
private readonly IList<Func<object, ValidationResult>> _validators;

private readonly Type _targetType = typeof(T);
Expand All @@ -41,7 +41,7 @@ protected override bool TryGetResult(out T result)
{
if (string.IsNullOrEmpty(input))
{
if (_targetType.IsValueType && _underlyingType == null && _defaultValue == null)
if (_targetType.IsValueType && _underlyingType == null && _defaultValue.HasValue)
{
Renderer.SetValidationResult(new ValidationResult("Value is required"));

Expand All @@ -50,7 +50,7 @@ protected override bool TryGetResult(out T result)
return false;
}

result = (T)_defaultValue;
result = _defaultValue;
}
else
{
Expand Down Expand Up @@ -121,7 +121,7 @@ protected override void InputTemplate(ScreenBuffer screenBuffer)
{
screenBuffer.WritePrompt(_message);

if (_defaultValue != null)
if (_defaultValue.HasValue)
{
screenBuffer.Write($"({_defaultValue}) ");
}
Expand Down
4 changes: 2 additions & 2 deletions Sharprompt/Forms/MultiSelect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public MultiSelect(string message, IEnumerable<T> items, int? pageSize, int mini
}

_message = message;
_selector = new Selector<T>(items, pageSize, null, valueSelector);
_selector = new Selector<T>(items, pageSize, Optional<T>.Empty, valueSelector);
_minimum = minimum;
_maximum = maximum;
_valueSelector = valueSelector;
Expand Down Expand Up @@ -115,7 +115,7 @@ protected override void InputTemplate(ScreenBuffer screenBuffer)

var subset = _selector.ToSubset();

foreach (T item in subset)
foreach (var item in subset)
{
var value = _valueSelector(item);

Expand Down
4 changes: 2 additions & 2 deletions Sharprompt/Forms/Select.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Sharprompt.Forms
{
internal class Select<T> : FormBase<T>
{
public Select(string message, IEnumerable<T> items, int? pageSize, object defaultValue, Func<T, string> valueSelector)
public Select(string message, IEnumerable<T> items, int? pageSize, Optional<T> defaultValue, Func<T, string> valueSelector)
: base(false)
{
_message = message;
Expand Down Expand Up @@ -79,7 +79,7 @@ protected override void InputTemplate(ScreenBuffer screenBuffer)

var subset = _selector.ToSubset();

foreach (T item in subset)
foreach (var item in subset)
{
var value = _valueSelector(item);

Expand Down
29 changes: 29 additions & 0 deletions Sharprompt/Internal/Optional.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Sharprompt.Internal
{
internal readonly struct Optional<T>
{
public Optional(T value)
{
HasValue = true;
Value = value;
}

public bool HasValue { get; }

public T Value { get; }

public static implicit operator T(Optional<T> optional) => optional.Value;

public static readonly Optional<T> Empty = new Optional<T>();

public static Optional<T> Create(T value)
{
return value == null ? Empty : new Optional<T>(value);
}

public static Optional<T> Create(object value)
{
return value == null ? Empty : new Optional<T>((T)value);
}
}
}
10 changes: 5 additions & 5 deletions Sharprompt/Internal/Selector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Sharprompt.Internal
{
internal class Selector<T>
{
public Selector(IEnumerable<T> items, int? pageSize, object defaultValue, Func<T, string> valueSelector)
public Selector(IEnumerable<T> items, int? pageSize, Optional<T> defaultValue, Func<T, string> valueSelector)
{
_items = items.ToArray();
_pageSize = pageSize ?? _items.Length;
Expand Down Expand Up @@ -88,18 +88,18 @@ private void InitializeCollection()
_pageCount = (_filteredSource.Length - 1) / _pageSize + 1;
}

private void InitializeDefaults(object defaultValue)
private void InitializeDefaults(Optional<T> defaultValue)
{
InitializeCollection();

if (defaultValue == null)
if (!defaultValue.HasValue)
{
return;
}

for (int i = 0; i < _filteredSource.Length; i++)
for (var i = 0; i < _filteredSource.Length; i++)
{
if (EqualityComparer<T>.Default.Equals(_filteredSource[i], (T)defaultValue))
if (EqualityComparer<T>.Default.Equals(_filteredSource[i], defaultValue))
{
_selectedIndex = i % _pageSize;
_selectedPage = i / _pageSize;
Expand Down
6 changes: 3 additions & 3 deletions Sharprompt/Prompt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class Prompt
{
public static T Input<T>(string message, object defaultValue = null, IList<Func<object, ValidationResult>> validators = null)
{
using var form = new Input<T>(message, defaultValue, validators);
using var form = new Input<T>(message, Optional<T>.Create(defaultValue), validators);

return form.Start();
}
Expand All @@ -35,14 +35,14 @@ public static T Select<T>(string message, int? pageSize = null, T? defaultValue
{
var items = EnumValue<T>.GetValues();

using var form = new Select<EnumValue<T>>(message, items, pageSize, (EnumValue<T>)defaultValue, x => x.DisplayName);
using var form = new Select<EnumValue<T>>(message, items, pageSize, Optional<EnumValue<T>>.Create(defaultValue), x => x.DisplayName);

return form.Start().Value;
}

public static T Select<T>(string message, IEnumerable<T> items, int? pageSize = null, object defaultValue = null, Func<T, string> valueSelector = null)
{
using var form = new Select<T>(message, items, pageSize, defaultValue, valueSelector ?? (x => x.ToString()));
using var form = new Select<T>(message, items, pageSize, Optional<T>.Create(defaultValue), valueSelector ?? (x => x.ToString()));

return form.Start();
}
Expand Down

0 comments on commit 030bb9a

Please sign in to comment.