-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathParser-String.cs
More file actions
80 lines (66 loc) · 2.93 KB
/
Copy pathParser-String.cs
File metadata and controls
80 lines (66 loc) · 2.93 KB
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
namespace Faithlife.Parsing;
public static partial class Parser
{
/// <summary>
/// Captures the parsed text as a string.
/// </summary>
public static IParser<string> Capture<T>(this IParser<T> parser) => new CaptureParser<T>(parser);
private sealed class CaptureParser<T> : Parser<string>
{
public CaptureParser(IParser<T> parser)
{
m_parser = parser;
}
public override string TryParse(bool skip, ref TextPosition position, out bool success)
{
var index = position.Index;
m_parser.TryParse(skip: true, ref position, out success);
return success && !skip ? position.Text.Substring(index, position.Index - index) : default!;
}
private readonly IParser<T> m_parser;
}
/// <summary>
/// Parses the specified string using ordinal (case-sensitive) comparison.
/// </summary>
public static IParser<string> String(string text) => String(text, StringComparison.Ordinal);
/// <summary>
/// Parses the specified string using the specified string comparison.
/// </summary>
public static IParser<string> String(string text, StringComparison comparison) => new StringParser(text, comparison);
private sealed class StringParser : Parser<string>
{
public StringParser(string text, StringComparison comparison) => (m_text, m_comparison) = (text, comparison);
public override string TryParse(bool skip, ref TextPosition position, out bool success)
{
var inputText = position.Text;
var inputIndex = position.Index;
var textLength = m_text.Length;
if (string.Compare(inputText, inputIndex, m_text, 0, textLength, m_comparison) == 0)
{
position = position.WithNextIndex(textLength);
success = true;
return m_comparison == StringComparison.Ordinal || skip ? m_text : inputText.Substring(inputIndex, textLength);
}
success = false;
return default!;
}
private readonly string m_text;
private readonly StringComparison m_comparison;
}
/// <summary>
/// Maps a successfully parsed string into a successfully parsed collection of characters.
/// </summary>
public static IParser<IReadOnlyList<char>> Chars(this IParser<string> textParser) => textParser.Select(text => text.ToCharArray());
/// <summary>
/// Maps a successfully parsed collection of characters into a successfully parsed string.
/// </summary>
public static IParser<string> String(this IParser<IEnumerable<char>> parser) => parser.Select(chars => new string(chars.ToArray()));
/// <summary>
/// Concatenates the successfully parsed collection of strings into a single successfully parsed string.
/// </summary>
public static IParser<string> Concat(this IParser<IEnumerable<string>> parser) => parser.Select(string.Concat);
/// <summary>
/// Joins the successfully parsed collection of strings into a single successfully parsed string using the specified separator.
/// </summary>
public static IParser<string> Join(this IParser<IEnumerable<string>> parser, string separator) => parser.Select(strings => string.Join(separator, strings));
}