-
Notifications
You must be signed in to change notification settings - Fork 9.8k
/
RouteTemplate.cs
142 lines (121 loc) · 4.53 KB
/
RouteTemplate.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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable enable
using System.Diagnostics;
using System.Linq;
using Microsoft.AspNetCore.Routing.Patterns;
namespace Microsoft.AspNetCore.Routing.Template;
/// <summary>
/// Represents the template for a route.
/// </summary>
[DebuggerDisplay("{DebuggerToString()}")]
public class RouteTemplate
{
private const string SeparatorString = "/";
/// <summary>
/// Constructs a new <see cref="RouteTemplate"/> instance given <paramref name="other"/>.
/// </summary>
/// <param name="other">A <see cref="RoutePattern"/> instance.</param>
public RouteTemplate(RoutePattern other)
{
ArgumentNullException.ThrowIfNull(other);
// RequiredValues will be ignored. RouteTemplate doesn't support them.
TemplateText = other.RawText;
Segments = new List<TemplateSegment>(other.PathSegments.Count);
foreach (var p in other.PathSegments)
{
Segments.Add(new TemplateSegment(p));
}
Parameters = new List<TemplatePart>();
for (var i = 0; i < Segments.Count; i++)
{
var segment = Segments[i];
for (var j = 0; j < segment.Parts.Count; j++)
{
var part = segment.Parts[j];
if (part.IsParameter)
{
Parameters.Add(part);
}
}
}
}
/// <summary>
/// Constructs a a new <see cref="RouteTemplate" /> instance given the <paramref name="template"/> string
/// and a list of <paramref name="segments"/>. Computes the parameters in the route template.
/// </summary>
/// <param name="template">A string representation of the route template.</param>
/// <param name="segments">A list of <see cref="TemplateSegment"/>.</param>
public RouteTemplate(string template, List<TemplateSegment> segments)
{
ArgumentNullException.ThrowIfNull(segments);
TemplateText = template;
Segments = segments;
Parameters = new List<TemplatePart>();
for (var i = 0; i < segments.Count; i++)
{
var segment = Segments[i];
for (var j = 0; j < segment.Parts.Count; j++)
{
var part = segment.Parts[j];
if (part.IsParameter)
{
Parameters.Add(part);
}
}
}
}
/// <summary>
/// Gets the string representation of the route template.
/// </summary>
public string? TemplateText { get; }
/// <summary>
/// Gets the list of <see cref="TemplatePart"/> that represent that parameters defined in the route template.
/// </summary>
public IList<TemplatePart> Parameters { get; }
/// <summary>
/// Gets the list of <see cref="TemplateSegment"/> that compromise the route template.
/// </summary>
public IList<TemplateSegment> Segments { get; }
/// <summary>
/// Gets the <see cref="TemplateSegment"/> at a given index.
/// </summary>
/// <param name="index">The index of the element to retrieve.</param>
/// <returns>A <see cref="TemplateSegment"/> instance.</returns>
public TemplateSegment? GetSegment(int index)
{
ArgumentOutOfRangeException.ThrowIfNegative(index);
return index >= Segments.Count ? null : Segments[index];
}
private string DebuggerToString()
{
return string.Join(SeparatorString, Segments.Select(s => s.DebuggerToString()));
}
/// <summary>
/// Gets the parameter matching the given name.
/// </summary>
/// <param name="name">The name of the parameter to match.</param>
/// <returns>The matching parameter or <c>null</c> if no parameter matches the given name.</returns>
public TemplatePart? GetParameter(string name)
{
for (var i = 0; i < Parameters.Count; i++)
{
var parameter = Parameters[i];
if (string.Equals(parameter.Name, name, StringComparison.OrdinalIgnoreCase))
{
return parameter;
}
}
return null;
}
/// <summary>
/// Converts the <see cref="RouteTemplate"/> to the equivalent
/// <see cref="RoutePattern"/>
/// </summary>
/// <returns>A <see cref="RoutePattern"/>.</returns>
public RoutePattern ToRoutePattern()
{
var segments = Segments.Select(s => s.ToRoutePatternPathSegment());
return RoutePatternFactory.Pattern(TemplateText, segments);
}
}