-
Notifications
You must be signed in to change notification settings - Fork 0
/
Uri.cs
127 lines (117 loc) · 4.5 KB
/
Uri.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
using System;
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using Recore.Text.Json.Serialization.Converters;
namespace Recore
{
/// <summary>
/// Represents an absolute URI.
/// </summary>
[JsonConverter(typeof(AbsoluteUriConverter))]
public class AbsoluteUri : Uri
{
/// <summary>
/// Initializes a new instance of <see cref="AbsoluteUri"/> with the given URI.
/// </summary>
public AbsoluteUri(string uriString) : base(uriString, UriKind.Absolute) { }
private AbsoluteUri(Uri baseUri, RelativeUri relativeUri) : base(baseUri, relativeUri) { }
/// <summary>
/// Appends a relative URI to an absolute URI.
/// </summary>
public AbsoluteUri Combine(string relativeUri) => Combine(new RelativeUri(relativeUri));
/// <summary>
/// Appends a relative URI to an absolute URI.
/// </summary>
public AbsoluteUri Combine(RelativeUri relativeUri) => new AbsoluteUri(this, relativeUri);
/// <summary>
/// Creates a new <see cref="AbsoluteUri"/>. Does not throw an exception if the <see cref="AbsoluteUri"/> cannot be created.
/// </summary>
public static bool TryCreate(string uriString, [NotNullWhen(true)] out AbsoluteUri? result)
{
result = null;
if (TryCreate(uriString, UriKind.Absolute, out Uri? value))
{
result = value.AsAbsoluteUri()!;
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// Represents a relative URI.
/// </summary>
[JsonConverter(typeof(RelativeUriConverter))]
public class RelativeUri : Uri
{
/// <summary>
/// Initializes a new instance of <see cref="RelativeUri"/> with the given URI.
/// </summary>
public RelativeUri(string uriString) : base(uriString, UriKind.Relative) { }
/// <summary>
/// Creates a new <see cref="RelativeUri"/>. Does not throw an exception if the <see cref="RelativeUri"/> cannot be created.
/// </summary>
public static bool TryCreate(string uriString, [NotNullWhen(true)] out RelativeUri? result)
{
result = null;
if (TryCreate(uriString, UriKind.Relative, out Uri? value))
{
result = value.AsRelativeUri()!;
return true;
}
else
{
return false;
}
}
}
/// <summary>
/// Extension methods for the <see cref="Uri"/> type.
/// </summary>
public static class UriExtensions
{
/// <summary>
/// Returns an instance of <see cref="AbsoluteUri"/> with the same value as <paramref name="uri"/>
/// if it is absolute, or null if it is relative.
/// </summary>
/// <remarks>
/// Because an instance of <see cref="Uri"/> may be neither <see cref="AbsoluteUri"/> nor <see cref="RelativeUri"/>,
/// patterns like <c>(AbsoluteUri)uri</c> or <c>uri as AbsoluteUri</c> cannot be used reliably.
/// <see cref="AsAbsoluteUri(Uri)"/> works as <c>uri as AbsoluteUri</c> would if <see cref="Uri"/> were an abstract base class.
/// It complements <see cref="Uri.IsAbsoluteUri"/> in this regard.
/// </remarks>
public static AbsoluteUri? AsAbsoluteUri(this Uri uri)
{
if (uri.IsAbsoluteUri)
{
return new AbsoluteUri(uri.AbsoluteUri);
}
else
{
return null;
}
}
/// <summary>
/// Returns an instance of <see cref="AbsoluteUri"/> with the same value as <paramref name="uri"/>
/// if it is absolute, or null if it is relative.
/// </summary>
/// <remarks>
/// Because an instance of <see cref="Uri"/> may be neither <see cref="AbsoluteUri"/> nor <see cref="RelativeUri"/>,
/// patterns like <c>(AbsoluteUri)uri</c> or <c>uri as AbsoluteUri</c> cannot be used reliably.
/// <see cref="AsRelativeUri(Uri)"/> works as <c>uri as RelativeUri</c> would if <see cref="Uri"/> were an abstract base class.
/// </remarks>
public static RelativeUri? AsRelativeUri(this Uri uri)
{
if (uri.IsAbsoluteUri)
{
return null;
}
else
{
return new RelativeUri(uri.ToString());
}
}
}
}