Skip to content

Commit d2c7a50

Browse files
committed
introduce PlaylistRef.TryParse, improve validation
1 parent fd7c25b commit d2c7a50

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

src/Client/Infrastructure/ArgumentValidator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Beefweb.Client.Infrastructure;
77
internal static partial class ArgumentValidator
88
{
99
[GeneratedRegex("^[a-z0-9_]+$")]
10-
private static partial Regex IdMatcher();
10+
public static partial Regex IdMatcher();
1111

1212
public static void ValidatePlaylistId(string? id,
1313
[CallerArgumentExpression(nameof(id))] string parameterName = "")

src/Client/PlaylistRef.cs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace Beefweb.Client;
1414
/// <summary>
1515
/// <see cref="PlaylistRef"/> referencing currently selected playlist.
1616
/// </summary>
17-
public static PlaylistRef Current { get; } = new("current");
17+
public static PlaylistRef Current { get; } = new(false, "current");
1818

1919
/// <summary>
2020
/// Playlist identifier.
@@ -36,6 +36,7 @@ namespace Beefweb.Client;
3636
public PlaylistRef(string id)
3737
{
3838
ArgumentValidator.ValidatePlaylistId(id);
39+
3940
Id = id;
4041
Index = -1;
4142
}
@@ -53,6 +54,18 @@ public PlaylistRef(int index)
5354
Index = index;
5455
}
5556

57+
private PlaylistRef(bool unused, int index)
58+
{
59+
Id = null;
60+
Index = index;
61+
}
62+
63+
private PlaylistRef(bool unused, string id)
64+
{
65+
Id = id;
66+
Index = -1;
67+
}
68+
5669
/// <summary>
5770
/// Implicitly converts <paramref name="index"/> to <see cref="PlaylistRef"/>.
5871
/// </summary>
@@ -89,9 +102,40 @@ public object GetValue()
89102
/// <returns>Parsed value of <paramref name="value"/>.</returns>
90103
public static PlaylistRef Parse(string value)
91104
{
92-
return int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var index)
93-
? new PlaylistRef(index)
94-
: new PlaylistRef(value);
105+
if (TryParse(value, out var playlistRef))
106+
return playlistRef;
107+
108+
throw new ArgumentException($"Invalid playlist reference '{value}'.", nameof(value));
109+
}
110+
111+
/// <summary>
112+
/// Tries to create <see cref="PlaylistRef"/> from string representation.
113+
/// </summary>
114+
/// <param name="value">String representation of playlist reference.</param>
115+
/// <param name="playlistRef">Parsed value.</param>
116+
/// <returns>Parsed value of <paramref name="value"/>.</returns>
117+
public static bool TryParse(string? value, out PlaylistRef playlistRef)
118+
{
119+
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var index))
120+
{
121+
if (index < 0)
122+
{
123+
playlistRef = default;
124+
return false;
125+
}
126+
127+
playlistRef = new PlaylistRef(false, index);
128+
return true;
129+
}
130+
131+
if (value != null && ArgumentValidator.IdMatcher().IsMatch(value))
132+
{
133+
playlistRef = new PlaylistRef(false, value);
134+
return true;
135+
}
136+
137+
playlistRef = default;
138+
return false;
95139
}
96140

97141
/// <inheritdoc />

src/CommandLineTool/Services/Extensions.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public static PlaylistInfo Get(this IList<PlaylistInfo> playlists, string playli
3636
{
3737
if (!zeroBasedIndices && playlistRef == "0")
3838
{
39-
throw new InvalidRequestException("Playlist index (0) is out of range.");
39+
throw IndexIsOutOfRange();
4040
}
4141

4242
return playlists.FirstOrDefault(p => p.Id == playlistRef) ??
@@ -46,10 +46,15 @@ public static PlaylistInfo Get(this IList<PlaylistInfo> playlists, string playli
4646
var realIndex = index.GetOffsetInclusive(playlists.Count);
4747
if (realIndex < 0 || realIndex >= playlists.Count)
4848
{
49-
throw new InvalidRequestException($"Playlist index ({playlistRef}) is out of range.");
49+
throw IndexIsOutOfRange();
5050
}
5151

5252
return playlists[realIndex];
53+
54+
InvalidRequestException IndexIsOutOfRange()
55+
{
56+
return new InvalidRequestException($"Playlist index ({playlistRef}) is out of range.");
57+
}
5358
}
5459

5560
public static IEnumerable<int> GetItems(this Range range, int totalCount)

tests/Client.Tests/PlaylistRefTests.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,24 @@ public void ShouldParse()
1818
PlaylistRef.Parse("123").Should().Be(new PlaylistRef(123));
1919
PlaylistRef.Parse("p321").Should().Be(new PlaylistRef("p321"));
2020
}
21+
22+
[Fact]
23+
public void ShouldTryParse()
24+
{
25+
PlaylistRef.TryParse("p1", out var pl).Should().BeTrue();
26+
pl.Should().Be(new PlaylistRef("p1"));
27+
28+
PlaylistRef.TryParse("current", out pl).Should().BeTrue();
29+
pl.Should().Be(PlaylistRef.Current);
30+
31+
PlaylistRef.TryParse("0", out pl).Should().BeTrue();
32+
pl.Should().Be(new PlaylistRef(0));
33+
34+
PlaylistRef.TryParse("1", out pl).Should().BeTrue();
35+
pl.Should().Be(new PlaylistRef(1));
36+
37+
PlaylistRef.TryParse("", out _).Should().BeFalse();
38+
PlaylistRef.TryParse("-1", out _).Should().BeFalse();
39+
PlaylistRef.TryParse("invalid?", out _).Should().BeFalse();
40+
}
2141
}

0 commit comments

Comments
 (0)