Skip to content

Commit b951525

Browse files
committed
Add TrySetValue and TryGetValue
1 parent 437512f commit b951525

File tree

5 files changed

+183
-1
lines changed

5 files changed

+183
-1
lines changed

Source/Common/JsonLdObject.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
namespace Schema.NET
22
{
33
using System;
4+
using System.Collections.Generic;
45
using System.Runtime.Serialization;
56
using Newtonsoft.Json;
67

@@ -45,6 +46,27 @@ public class JsonLdObject : IEquatable<JsonLdObject>
4546
[DataMember(Name = "@id", Order = 2)]
4647
public virtual Uri? Id { get; set; }
4748

49+
/// <summary>
50+
/// Attempts to set the Schema.org <paramref name="property"/> on the current object with the specified <paramref name="value"/>.
51+
/// </summary>
52+
/// <param name="property">The property to set the value on.</param>
53+
/// <param name="value">The value to set on the property</param>
54+
/// <returns><see langword="true"/> when the value has successfully been set; otherwise, <see langword="false"/>.</returns>
55+
public virtual bool TrySetValue(string property, IEnumerable<object> value) => false;
56+
57+
/// <summary>
58+
/// Attempts to retrieve the <typeparamref name="TValue"/> from <paramref name="property"/>.
59+
/// </summary>
60+
/// <typeparam name="TValue">The type of value you want to retrieve.</typeparam>
61+
/// <param name="property">The property to get the value from.</param>
62+
/// <param name="result">The value on the property.</param>
63+
/// <returns><see langword="true"/> when the value has successfully been retrieved; otherwise, <see langword="false"/>.</returns>
64+
public virtual bool TryGetValue<TValue>(string property, out OneOrMany<TValue> result)
65+
{
66+
result = default;
67+
return false;
68+
}
69+
4870
/// <inheritdoc/>
4971
public bool Equals(JsonLdObject? other)
5072
{

Tests/Schema.NET.Test/ThingTest.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,88 @@ public void ToStringWithNullAssignedProperty_ReturnsExpectedJsonLd()
199199
Assert.Equal(expectedJson, thing.ToString());
200200
}
201201

202+
[Fact]
203+
public void TrySetValue_ValidProperty()
204+
{
205+
var thing = new Thing();
206+
207+
Assert.True(thing.TrySetValue("Name", new[] { "TestName" }));
208+
Assert.Equal("TestName", thing.Name);
209+
}
210+
211+
[Fact]
212+
public void TrySetValue_InvalidProperty()
213+
{
214+
var thing = new Thing();
215+
216+
Assert.False(thing.TrySetValue("InvalidName", new[] { "TestName" }));
217+
}
218+
219+
[Fact]
220+
public void TrySetValue_CaseInsensitive()
221+
{
222+
var thing = new Thing();
223+
224+
Assert.True(thing.TrySetValue("name", new[] { "TestName" }));
225+
Assert.Equal("TestName", thing.Name);
226+
}
227+
228+
[Fact]
229+
public void TryGetValue_ValidProperty_OneOrMany()
230+
{
231+
var thing = new Thing
232+
{
233+
Name = "TestName",
234+
};
235+
236+
Assert.True(thing.TryGetValue<string>("Name", out var result));
237+
Assert.Equal("TestName", result);
238+
}
239+
240+
[Fact]
241+
public void TryGetValue_ValidProperty_Values()
242+
{
243+
var thing = new Thing
244+
{
245+
Identifier = new Uri("https://example.org/test-identifier"),
246+
};
247+
248+
Assert.True(thing.TryGetValue<Uri>("Identifier", out var result));
249+
var identifier = Assert.Single(result);
250+
Assert.Equal(new Uri("https://example.org/test-identifier"), identifier);
251+
}
252+
253+
[Fact]
254+
public void TryGetValue_InvalidProperty_InvalidName()
255+
{
256+
var thing = new Thing();
257+
258+
Assert.False(thing.TryGetValue<string>("InvalidName", out _));
259+
}
260+
261+
[Fact]
262+
public void TryGetValue_InvalidProperty_InvalidType()
263+
{
264+
var thing = new Thing
265+
{
266+
Name = "TestName",
267+
};
268+
269+
Assert.False(thing.TryGetValue<Uri>("Name", out _));
270+
}
271+
272+
[Fact]
273+
public void TryGetValue_CaseInsensitive()
274+
{
275+
var thing = new Thing
276+
{
277+
Name = "TestName",
278+
};
279+
280+
Assert.True(thing.TryGetValue<string>("name", out var result));
281+
Assert.Equal("TestName", result);
282+
}
283+
202284
private static void CompareEqual<T>(T a, T? b)
203285
{
204286
Assert.NotNull(a);

Tools/Schema.NET.Tool/GeneratorModels/GeneratorSchemaProperty.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ public GeneratorSchemaProperty(GeneratorSchemaClass @class, string jsonName, str
2828

2929
public ICollection<GeneratorSchemaPropertyType> Types { get; } = new List<GeneratorSchemaPropertyType>();
3030

31+
public IEnumerable<string> CSharpTypes => this.Types.SelectMany(x => x.CSharpTypeStrings);
32+
3133
public string PropertyTypeString
3234
{
3335
get
3436
{
35-
var propertyTypes = this.Types.SelectMany(x => x.CSharpTypeStrings).ToArray();
37+
var propertyTypes = this.CSharpTypes.ToArray();
3638
var propertyTypesString = string.Join(", ", propertyTypes);
3739
if (propertyTypes.Length == 1)
3840
{

Tools/Schema.NET.Tool/SchemaSourceGenerator.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ private static string RenderClass(GeneratorSchemaClass schemaClass)
9393
$@"namespace Schema.NET
9494
{{
9595
using System;
96+
using System.Collections.Generic;
9697
using System.Runtime.Serialization;
9798
using Newtonsoft.Json;
9899
@@ -126,6 +127,58 @@ public partial interface I{schemaClass.Name}{interfaceImplements}
126127
[JsonConverter(typeof({property.JsonConverterType}))]
127128
public{GetAccessModifier(property)} {property.PropertyTypeString} {property.Name} {{ get; set; }}")}
128129

130+
/// <inheritdoc/>
131+
public override bool TrySetValue(string property, IEnumerable<object> value)
132+
{{
133+
if (string.IsNullOrWhiteSpace(property))
134+
{{
135+
return false;
136+
}}
137+
138+
var success = false;
139+
{SourceUtility.RenderItems(allProperties, property => $@"if (""{property.Name}"".Equals(property, StringComparison.OrdinalIgnoreCase))
140+
{{
141+
this.{property.Name} = new(value);
142+
success = true;
143+
}}
144+
else ")}
145+
{{
146+
success = base.TrySetValue(property, value);
147+
}}
148+
149+
return success;
150+
}}
151+
152+
/// <inheritdoc/>
153+
public override bool TryGetValue<TValue>(string property, out OneOrMany<TValue> result)
154+
{{
155+
if (string.IsNullOrWhiteSpace(property))
156+
{{
157+
result = default;
158+
return false;
159+
}}
160+
161+
var success = false;
162+
{SourceUtility.RenderItems(allProperties, property => $@"if (""{property.Name}"".Equals(property, StringComparison.OrdinalIgnoreCase))
163+
{{
164+
{SourceUtility.RenderItems(property.CSharpTypes, (propertyType, index) => $@"if (typeof({propertyType}) == typeof(TValue))
165+
{{
166+
result = (OneOrMany<TValue>)(IValues)this.{property.Name}{(property.CSharpTypes.Count() > 1 ? $".Value{index + 1}" : string.Empty)};
167+
success = true;
168+
}}
169+
else ")}
170+
{{
171+
result = default;
172+
}}
173+
}}
174+
else ")}
175+
{{
176+
success = base.TryGetValue(property, out result);
177+
}}
178+
179+
return success;
180+
}}
181+
129182
/// <inheritdoc/>
130183
public bool Equals({schemaClass.Name} other)
131184
{{

Tools/Schema.NET.Tool/SourceUtility.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ public static string RenderItems<T>(IEnumerable<T> items, Func<T, string> action
4242
return stringBuilder.ToString();
4343
}
4444

45+
public static string RenderItems<T>(IEnumerable<T> items, Func<T, int, string> action)
46+
{
47+
if (items is null)
48+
{
49+
throw new ArgumentNullException(nameof(items));
50+
}
51+
52+
if (action is null)
53+
{
54+
throw new ArgumentNullException(nameof(action));
55+
}
56+
57+
var stringBuilder = new StringBuilder();
58+
var i = 0;
59+
foreach (var item in items)
60+
{
61+
stringBuilder.Append(action(item, i));
62+
i++;
63+
}
64+
65+
return stringBuilder.ToString();
66+
}
67+
4568
public static string RenderDoc(int indent, string? text)
4669
{
4770
if (text == null)

0 commit comments

Comments
 (0)