/
JsonProperty.cs
142 lines (130 loc) · 5.68 KB
/
JsonProperty.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.
using System;
using System.Diagnostics;
namespace System.Text.Json
{
/// <summary>
/// Represents a single property for a JSON object.
/// </summary>
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public readonly struct JsonProperty
{
/// <summary>
/// The value of this property.
/// </summary>
public JsonElement Value { get; }
private string? _name { get; }
internal JsonProperty(JsonElement value, string? name = null)
{
Value = value;
_name = name;
}
/// <summary>
/// The name of this property.
/// </summary>
public string Name => _name ?? Value.GetPropertyName();
/// <summary>
/// Compares <paramref name="text" /> to the name of this property.
/// </summary>
/// <param name="text">The text to compare against.</param>
/// <returns>
/// <see langword="true" /> if the name of this property matches <paramref name="text"/>,
/// <see langword="false" /> otherwise.
/// </returns>
/// <exception cref="InvalidOperationException">
/// This value's <see cref="Type"/> is not <see cref="JsonTokenType.PropertyName"/>.
/// </exception>
/// <remarks>
/// This method is functionally equal to doing an ordinal comparison of <paramref name="text" /> and
/// <see cref="Name" />, but can avoid creating the string instance.
/// </remarks>
public bool NameEquals(string? text)
{
return NameEquals(text.AsSpan());
}
/// <summary>
/// Compares the text represented by <paramref name="utf8Text" /> to the name of this property.
/// </summary>
/// <param name="utf8Text">The UTF-8 encoded text to compare against.</param>
/// <returns>
/// <see langword="true" /> if the name of this property has the same UTF-8 encoding as
/// <paramref name="utf8Text" />, <see langword="false" /> otherwise.
/// </returns>
/// <exception cref="InvalidOperationException">
/// This value's <see cref="Type"/> is not <see cref="JsonTokenType.PropertyName"/>.
/// </exception>
/// <remarks>
/// This method is functionally equal to doing an ordinal comparison of <paramref name="utf8Text" /> and
/// <see cref="Name" />, but can avoid creating the string instance.
/// </remarks>
public bool NameEquals(ReadOnlySpan<byte> utf8Text)
{
return Value.TextEqualsHelper(utf8Text, isPropertyName: true, shouldUnescape: true);
}
/// <summary>
/// Compares <paramref name="text" /> to the name of this property.
/// </summary>
/// <param name="text">The text to compare against.</param>
/// <returns>
/// <see langword="true" /> if the name of this property matches <paramref name="text"/>,
/// <see langword="false" /> otherwise.
/// </returns>
/// <exception cref="InvalidOperationException">
/// This value's <see cref="Type"/> is not <see cref="JsonTokenType.PropertyName"/>.
/// </exception>
/// <remarks>
/// This method is functionally equal to doing an ordinal comparison of <paramref name="text" /> and
/// <see cref="Name" />, but can avoid creating the string instance.
/// </remarks>
public bool NameEquals(ReadOnlySpan<char> text)
{
return Value.TextEqualsHelper(text, isPropertyName: true);
}
internal bool EscapedNameEquals(ReadOnlySpan<byte> utf8Text)
{
return Value.TextEqualsHelper(utf8Text, isPropertyName: true, shouldUnescape: false);
}
/// <summary>
/// Write the property into the provided writer as a named JSON object property.
/// </summary>
/// <param name="writer">The writer.</param>
/// <exception cref="ArgumentNullException">
/// The <paramref name="writer"/> parameter is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// This <see cref="Name"/>'s length is too large to be a JSON object property.
/// </exception>
/// <exception cref="InvalidOperationException">
/// This <see cref="Value"/>'s <see cref="JsonElement.ValueKind"/> would result in an invalid JSON.
/// </exception>
/// <exception cref="ObjectDisposedException">
/// The parent <see cref="JsonDocument"/> has been disposed.
/// </exception>>
public void WriteTo(Utf8JsonWriter writer)
{
if (writer is null)
{
ThrowHelper.ThrowArgumentNullException(nameof(writer));
}
writer.WritePropertyName(Name);
Value.WriteTo(writer);
}
/// <summary>
/// Provides a <see cref="string"/> representation of the property for
/// debugging purposes.
/// </summary>
/// <returns>
/// A string containing the un-interpreted value of the property, beginning
/// at the declaring open-quote and ending at the last character that is part of
/// the value.
/// </returns>
public override string ToString()
{
return Value.GetPropertyRawText();
}
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay
=> Value.ValueKind == JsonValueKind.Undefined ? "<Undefined>" : $"\"{ToString()}\"";
}
}