Skip to content

Commit 4544d19

Browse files
authored
Refactor naming rule and optimize (#245)
1 parent 89b2cb1 commit 4544d19

File tree

10 files changed

+88
-103
lines changed

10 files changed

+88
-103
lines changed

Sharprompt.Tests/PaginatorTests.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ public void Basic()
1313
{
1414
var paginator = new Paginator<int>(Enumerable.Range(0, 20), 5, Optional<int>.Empty, x => x.ToString());
1515

16-
var subset1 = paginator.ToSubset();
16+
var currentItems1 = paginator.CurrentItems;
1717

18-
Assert.Equal(5, subset1.Count);
19-
Assert.Equal(new[] { 0, 1, 2, 3, 4 }, subset1);
18+
Assert.Equal(5, currentItems1.Length);
19+
Assert.Equal(new[] { 0, 1, 2, 3, 4 }, currentItems1.ToArray());
2020

2121
paginator.NextPage();
2222

23-
var subset2 = paginator.ToSubset();
23+
var currentItems2 = paginator.CurrentItems;
2424

25-
Assert.Equal(5, subset2.Count);
26-
Assert.Equal(new[] { 5, 6, 7, 8, 9 }, subset2);
25+
Assert.Equal(5, currentItems2.Length);
26+
Assert.Equal(new[] { 5, 6, 7, 8, 9 }, currentItems2.ToArray());
2727
}
2828

2929
[Fact]
@@ -33,10 +33,10 @@ public void Filter_NotEmpty()
3333

3434
paginator.UpdateFilter("0");
3535

36-
var subset = paginator.ToSubset();
36+
var currentItems = paginator.CurrentItems;
3737

38-
Assert.Equal(2, subset.Count);
39-
Assert.Equal(new[] { 0, 10 }, subset);
38+
Assert.Equal(2, currentItems.Length);
39+
Assert.Equal(new[] { 0, 10 }, currentItems.ToArray());
4040
}
4141

4242
[Fact]
@@ -46,9 +46,9 @@ public void Filter_Empty()
4646

4747
paginator.UpdateFilter("x");
4848

49-
var subset = paginator.ToSubset();
49+
var subset = paginator.CurrentItems;
5050

51-
Assert.Empty(subset);
51+
Assert.True(subset.IsEmpty);
5252
}
5353

5454
[Fact]

Sharprompt/Forms/FormBase.cs

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -50,38 +50,6 @@ public T Start()
5050
}
5151
}
5252

53-
protected bool TryGetResult([NotNullWhen(true)] out T? result)
54-
{
55-
do
56-
{
57-
var keyInfo = _consoleDriver.ReadKey();
58-
59-
if (keyInfo.Key == ConsoleKey.Enter)
60-
{
61-
return HandleEnter(out result);
62-
}
63-
64-
if (KeyHandlerMaps.TryGetValue(keyInfo.Key, out var keyHandler) && keyHandler(keyInfo))
65-
{
66-
continue;
67-
}
68-
69-
if (!char.IsControl(keyInfo.KeyChar))
70-
{
71-
HandleTextInput(keyInfo);
72-
}
73-
else
74-
{
75-
_consoleDriver.Beep();
76-
}
77-
78-
} while (_consoleDriver.KeyAvailable);
79-
80-
result = default;
81-
82-
return false;
83-
}
84-
8553
protected abstract void InputTemplate(OffscreenBuffer offscreenBuffer);
8654

8755
protected abstract void FinishTemplate(OffscreenBuffer offscreenBuffer, T result);
@@ -116,6 +84,38 @@ protected bool TryValidate([NotNullWhen(true)] object? input, IList<Func<object?
11684
return true;
11785
}
11886

87+
private bool TryGetResult([NotNullWhen(true)] out T? result)
88+
{
89+
do
90+
{
91+
var keyInfo = _consoleDriver.ReadKey();
92+
93+
if (keyInfo.Key == ConsoleKey.Enter)
94+
{
95+
return HandleEnter(out result);
96+
}
97+
98+
if (KeyHandlerMaps.TryGetValue(keyInfo.Key, out var keyHandler) && keyHandler(keyInfo))
99+
{
100+
continue;
101+
}
102+
103+
if (!char.IsControl(keyInfo.KeyChar))
104+
{
105+
HandleTextInput(keyInfo);
106+
}
107+
else
108+
{
109+
_consoleDriver.Beep();
110+
}
111+
112+
} while (_consoleDriver.KeyAvailable);
113+
114+
result = default;
115+
116+
return false;
117+
}
118+
119119
private void CancellationHandler()
120120
{
121121
_formRenderer.Cancel();

Sharprompt/Forms/InputForm.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ protected override bool HandleEnter([NotNullWhen(true)] out T? result)
5656
{
5757
if (string.IsNullOrEmpty(input))
5858
{
59-
if (TypeHelper<T>.IsValueType && !_defaultValue.HasValue)
59+
if (!TypeHelper<T>.IsNullable && !_defaultValue.HasValue)
6060
{
6161
SetError(Resource.Validation_Required);
6262

Sharprompt/Forms/MultiSelectForm.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,16 @@ public MultiSelectForm(MultiSelectOptions<T> options)
4343
protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
4444
{
4545
offscreenBuffer.WritePrompt(_options.Message);
46-
offscreenBuffer.Write(_paginator.FilterTerm);
46+
offscreenBuffer.Write(_paginator.FilterKeyword);
4747

4848
offscreenBuffer.PushCursor();
4949

50-
if (string.IsNullOrEmpty(_paginator.FilterTerm))
50+
if (string.IsNullOrEmpty(_paginator.FilterKeyword))
5151
{
5252
offscreenBuffer.WriteHint(Resource.MultiSelectForm_Message_Hint);
5353
}
5454

55-
var subset = _paginator.ToSubset();
56-
57-
foreach (var item in subset)
55+
foreach (var item in _paginator.CurrentItems)
5856
{
5957
var value = _options.TextSelector(item);
6058

@@ -80,7 +78,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
8078
if (_paginator.PageCount > 1)
8179
{
8280
offscreenBuffer.WriteLine();
83-
offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.SelectedPage + 1, _paginator.PageCount));
81+
offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.CurrentPage + 1, _paginator.PageCount));
8482
}
8583
}
8684

@@ -197,7 +195,7 @@ private bool HandleAWithControl(ConsoleKeyInfo keyInfo)
197195
}
198196
else
199197
{
200-
foreach (var item in _paginator.FilteredItems)
198+
foreach (var item in _paginator)
201199
{
202200
_selectedItems.Add(item);
203201
}
@@ -213,7 +211,7 @@ private bool HandleIWithControl(ConsoleKeyInfo keyInfo)
213211
return false;
214212
}
215213

216-
var invertedItems = _paginator.FilteredItems.Except(_selectedItems).ToArray();
214+
var invertedItems = _paginator.Except(_selectedItems).ToArray();
217215

218216
_selectedItems.Clear();
219217

Sharprompt/Forms/SelectForm.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,11 @@ public SelectForm(SelectOptions<T> options)
3232
protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
3333
{
3434
offscreenBuffer.WritePrompt(_options.Message);
35-
offscreenBuffer.Write(_paginator.FilterTerm);
35+
offscreenBuffer.Write(_paginator.FilterKeyword);
3636

3737
offscreenBuffer.PushCursor();
3838

39-
var subset = _paginator.ToSubset();
40-
41-
foreach (var item in subset)
39+
foreach (var item in _paginator.CurrentItems)
4240
{
4341
var value = _options.TextSelector(item);
4442

@@ -57,7 +55,7 @@ protected override void InputTemplate(OffscreenBuffer offscreenBuffer)
5755
if (_paginator.PageCount > 1)
5856
{
5957
offscreenBuffer.WriteLine();
60-
offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.SelectedPage + 1, _paginator.PageCount));
58+
offscreenBuffer.WriteHint(_options.Pagination(_paginator.TotalCount, _paginator.CurrentPage + 1, _paginator.PageCount));
6159
}
6260
}
6361

Sharprompt/Internal/Paginator.cs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System;
2+
using System.Collections;
23
using System.Collections.Generic;
34
using System.Diagnostics.CodeAnalysis;
45
using System.Linq;
56

67
namespace Sharprompt.Internal;
78

8-
internal class Paginator<T> where T : notnull
9+
internal class Paginator<T> : IEnumerable<T> where T : notnull
910
{
1011
public Paginator(IEnumerable<T> items, int pageSize, Optional<T> defaultValue, Func<T, string> textSelector)
1112
{
@@ -20,37 +21,38 @@ public Paginator(IEnumerable<T> items, int pageSize, Optional<T> defaultValue, F
2021
private readonly int _pageSize;
2122
private readonly Func<T, string> _textSelector;
2223

24+
private T[] _filteredItems = Array.Empty<T>();
2325
private int _selectedIndex = -1;
2426

25-
public T[] FilteredItems { get; private set; } = Array.Empty<T>();
27+
public ReadOnlySpan<T> CurrentItems => new(_filteredItems, _pageSize * CurrentPage, Count);
2628

2729
public int PageCount { get; private set; }
2830

29-
public int SelectedPage { get; private set; }
31+
public int CurrentPage { get; private set; }
3032

31-
public int Count => Math.Min(FilteredItems.Length - (_pageSize * SelectedPage), _pageSize);
33+
public int Count => Math.Min(_filteredItems.Length - (_pageSize * CurrentPage), _pageSize);
3234

33-
public int TotalCount => FilteredItems.Length;
35+
public int TotalCount => _filteredItems.Length;
3436

35-
public string FilterTerm { get; private set; } = "";
37+
public string FilterKeyword { get; private set; } = "";
3638

3739
public bool TryGetSelectedItem([NotNullWhen(true)] out T? selectedItem)
3840
{
39-
if (FilteredItems.Length == 1)
41+
if (_filteredItems.Length == 1)
4042
{
41-
selectedItem = FilteredItems[0];
43+
selectedItem = _filteredItems[0];
4244

4345
return true;
4446
}
4547

46-
if (_selectedIndex == -1 || FilteredItems.Length == 0)
48+
if (_selectedIndex == -1 || _filteredItems.Length == 0)
4749
{
4850
selectedItem = default;
4951

5052
return false;
5153
}
5254

53-
selectedItem = FilteredItems[(_pageSize * SelectedPage) + _selectedIndex];
55+
selectedItem = _filteredItems[(_pageSize * CurrentPage) + _selectedIndex];
5456

5557
return true;
5658
}
@@ -72,8 +74,8 @@ public void NextPage()
7274
return;
7375
}
7476

75-
SelectedPage = SelectedPage >= PageCount - 1 ? 0 : SelectedPage + 1;
7677
_selectedIndex = -1;
78+
CurrentPage = CurrentPage >= PageCount - 1 ? 0 : CurrentPage + 1;
7779
}
7880

7981
public void PreviousPage()
@@ -83,45 +85,47 @@ public void PreviousPage()
8385
return;
8486
}
8587

86-
SelectedPage = SelectedPage <= 0 ? PageCount - 1 : SelectedPage - 1;
8788
_selectedIndex = -1;
89+
CurrentPage = CurrentPage <= 0 ? PageCount - 1 : CurrentPage - 1;
8890
}
8991

90-
public void UpdateFilter(string term)
92+
public void UpdateFilter(string keyword)
9193
{
92-
FilterTerm = term;
94+
FilterKeyword = keyword;
9395

9496
_selectedIndex = -1;
95-
SelectedPage = 0;
97+
CurrentPage = 0;
9698

97-
UpdateItems();
99+
UpdateFilteredItems();
98100
}
99101

100-
public ArraySegment<T> ToSubset() => new(FilteredItems, _pageSize * SelectedPage, Count);
102+
public IEnumerator<T> GetEnumerator() => (IEnumerator<T>)_filteredItems.GetEnumerator();
101103

102-
private void UpdateItems()
104+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
105+
106+
private void UpdateFilteredItems()
103107
{
104-
FilteredItems = _items.Where(x => _textSelector(x).IndexOf(FilterTerm, StringComparison.OrdinalIgnoreCase) != -1)
105-
.ToArray();
108+
_filteredItems = _items.Where(x => _textSelector(x).IndexOf(FilterKeyword, StringComparison.OrdinalIgnoreCase) != -1)
109+
.ToArray();
106110

107-
PageCount = (FilteredItems.Length - 1) / _pageSize + 1;
111+
PageCount = (_filteredItems.Length - 1) / _pageSize + 1;
108112
}
109113

110114
private void InitializeDefaults(Optional<T> defaultValue)
111115
{
112-
UpdateItems();
116+
UpdateFilteredItems();
113117

114118
if (!defaultValue.HasValue)
115119
{
116120
return;
117121
}
118122

119-
for (var i = 0; i < FilteredItems.Length; i++)
123+
for (var i = 0; i < _filteredItems.Length; i++)
120124
{
121-
if (EqualityComparer<T>.Default.Equals(FilteredItems[i], defaultValue))
125+
if (EqualityComparer<T>.Default.Equals(_filteredItems[i], defaultValue))
122126
{
123127
_selectedIndex = i % _pageSize;
124-
SelectedPage = i / _pageSize;
128+
CurrentPage = i / _pageSize;
125129

126130
break;
127131
}

Sharprompt/Internal/PropertyMetadata.cs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ public PropertyMetadata(object model, PropertyInfo propertyInfo)
3030
.Select(x => new ValidationAttributeAdapter(x).GetValidator(propertyInfo.Name, model))
3131
.ToArray();
3232
ItemsProvider = GetItemsProvider(propertyInfo);
33-
BindIgnore = propertyInfo.GetCustomAttribute<BindIgnoreAttribute>() is not null;
3433
}
3534

3635
public PropertyInfo PropertyInfo { get; }
@@ -45,7 +44,6 @@ public PropertyMetadata(object model, PropertyInfo propertyInfo)
4544
public object? DefaultValue { get; }
4645
public IReadOnlyList<Func<object?, ValidationResult?>> Validators { get; }
4746
public IItemsProvider ItemsProvider { get; }
48-
public bool BindIgnore { get; set; }
4947

5048
public FormType DetermineFormType()
5149
{
@@ -59,22 +57,12 @@ public FormType DetermineFormType()
5957
return FormType.Confirm;
6058
}
6159

62-
if (!IsCollection && ItemsProvider is not NullItemsProvider)
60+
if (ItemsProvider is not NullItemsProvider)
6361
{
64-
return FormType.Select;
62+
return IsCollection ? FormType.MultiSelect : FormType.Select;
6563
}
6664

67-
if (IsCollection && ItemsProvider is not NullItemsProvider)
68-
{
69-
return FormType.MultiSelect;
70-
}
71-
72-
if (IsCollection && ItemsProvider is NullItemsProvider)
73-
{
74-
return FormType.List;
75-
}
76-
77-
return FormType.Input;
65+
return IsCollection ? FormType.List : FormType.Input;
7866
}
7967

8068
private IItemsProvider GetItemsProvider(PropertyInfo propertyInfo)

Sharprompt/Internal/PropertyMetadataFactory.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ internal static class PropertyMetadataFactory
99
public static IReadOnlyList<PropertyMetadata> Create<T>(T model) where T : notnull
1010
{
1111
return typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance)
12-
.Where(x => x.CanWrite)
12+
.Where(x => x.CanWrite && x.GetCustomAttribute<BindIgnoreAttribute>() is null)
1313
.Select(x => new PropertyMetadata(model, x))
14-
.Where(x => !x.BindIgnore)
1514
.OrderBy(x => x.Order)
1615
.ToArray();
1716
}

0 commit comments

Comments
 (0)