-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
StartsWith.cs
150 lines (141 loc) · 5.53 KB
/
StartsWith.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
namespace SuperLinq.Async;
public static partial class AsyncSuperEnumerable
{
/// <summary>
/// Determines whether the beginning of the first sequence is
/// equivalent to the second sequence, using the default equality
/// comparer.
/// </summary>
/// <typeparam name="T">Type of elements.</typeparam>
/// <param name="first">The sequence to check.</param>
/// <param name="second">The sequence to compare to.</param>
/// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
/// <returns>
/// <see langword="true"/> if <paramref name="first" /> begins with elements
/// equivalent to <paramref name="second" />.
/// </returns>
/// <remarks>
/// This is the <see cref="IAsyncEnumerable{T}" /> equivalent of
/// <see cref="string.StartsWith(string)" /> and it calls
/// <see cref="IEqualityComparer{T}.Equals(T,T)" /> using
/// <see cref="EqualityComparer{T}.Default"/> on pairs of elements at
/// the same index.
/// </remarks>
public static ValueTask<bool> StartsWith<T>(
this IAsyncEnumerable<T> first,
IEnumerable<T> second,
CancellationToken cancellationToken = default
)
{
ArgumentNullException.ThrowIfNull(first);
ArgumentNullException.ThrowIfNull(second);
return StartsWith(first, second.ToAsyncEnumerable(), comparer: null, cancellationToken);
}
/// <summary>
/// Determines whether the beginning of the first sequence is
/// equivalent to the second sequence, using the default equality
/// comparer.
/// </summary>
/// <typeparam name="T">Type of elements.</typeparam>
/// <param name="first">The sequence to check.</param>
/// <param name="second">The sequence to compare to.</param>
/// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
/// <returns>
/// <see langword="true"/> if <paramref name="first" /> begins with elements
/// equivalent to <paramref name="second" />.
/// </returns>
/// <remarks>
/// This is the <see cref="IAsyncEnumerable{T}" /> equivalent of
/// <see cref="string.StartsWith(string)" /> and it calls
/// <see cref="IEqualityComparer{T}.Equals(T,T)" /> using
/// <see cref="EqualityComparer{T}.Default"/> on pairs of elements at
/// the same index.
/// </remarks>
public static ValueTask<bool> StartsWith<T>(
this IAsyncEnumerable<T> first,
IAsyncEnumerable<T> second,
CancellationToken cancellationToken = default
)
{
return StartsWith(first, second, comparer: null, cancellationToken);
}
/// <summary>
/// Determines whether the beginning of the first sequence is
/// equivalent to the second sequence, using the specified element
/// equality comparer.
/// </summary>
/// <typeparam name="T">Type of elements.</typeparam>
/// <param name="first">The sequence to check.</param>
/// <param name="second">The sequence to compare to.</param>
/// <param name="comparer">Equality comparer to use.</param>
/// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
/// <returns>
/// <see langword="true"/> if <paramref name="first" /> begins with elements
/// equivalent to <paramref name="second" />.
/// </returns>
/// <remarks>
/// This is the <see cref="IAsyncEnumerable{T}" /> equivalent of
/// <see cref="string.StartsWith(string)" /> and
/// it calls <see cref="IEqualityComparer{T}.Equals(T,T)" /> on pairs
/// of elements at the same index.
/// </remarks>
public static ValueTask<bool> StartsWith<T>(
this IAsyncEnumerable<T> first,
IEnumerable<T> second,
IEqualityComparer<T>? comparer,
CancellationToken cancellationToken = default
)
{
ArgumentNullException.ThrowIfNull(first);
ArgumentNullException.ThrowIfNull(second);
return StartsWith(first, second.ToAsyncEnumerable(), comparer, cancellationToken);
}
/// <summary>
/// Determines whether the beginning of the first sequence is
/// equivalent to the second sequence, using the specified element
/// equality comparer.
/// </summary>
/// <typeparam name="T">Type of elements.</typeparam>
/// <param name="first">The sequence to check.</param>
/// <param name="second">The sequence to compare to.</param>
/// <param name="comparer">Equality comparer to use.</param>
/// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
/// <returns>
/// <see langword="true"/> if <paramref name="first" /> begins with elements
/// equivalent to <paramref name="second" />.
/// </returns>
/// <remarks>
/// This is the <see cref="IAsyncEnumerable{T}" /> equivalent of
/// <see cref="string.StartsWith(string)" /> and
/// it calls <see cref="IEqualityComparer{T}.Equals(T,T)" /> on pairs
/// of elements at the same index.
/// </remarks>
public static ValueTask<bool> StartsWith<T>(
this IAsyncEnumerable<T> first,
IAsyncEnumerable<T> second,
IEqualityComparer<T>? comparer,
CancellationToken cancellationToken = default
)
{
ArgumentNullException.ThrowIfNull(first);
ArgumentNullException.ThrowIfNull(second);
comparer ??= EqualityComparer<T>.Default;
return Core(first, second, comparer, cancellationToken);
static async ValueTask<bool> Core(
IAsyncEnumerable<T> first,
IAsyncEnumerable<T> second,
IEqualityComparer<T>? comparer,
CancellationToken cancellationToken
)
{
var snd = await second.ToListAsync(cancellationToken).ConfigureAwait(false);
return await first.Take(snd.Count)
.SequenceEqualAsync(
snd.ToAsyncEnumerable(),
comparer,
cancellationToken
)
.ConfigureAwait(false);
}
}
}