Skip to content

Commit db00544

Browse files
committed
fail discrimination more softly, add xml comments
1 parent 48ad5a8 commit db00544

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

YamlDotNet/Serialization/BufferedDeserialization/TypeDiscriminators/KeyValueTypeDiscriminator.cs

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,28 @@
77

88
namespace YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators
99
{
10+
/// <summary>
11+
/// A TypeDiscriminator that discriminates which type to deserialize a yaml stream into by checking the value
12+
/// of a known key.
13+
/// </summary>
1014
public class KeyValueTypeDiscriminator : ITypeDiscriminator
1115
{
1216
public Type BaseType { get; private set; }
1317
private readonly string targetKey;
1418
private readonly IDictionary<string, Type> typeMapping;
1519

20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="KeyValueTypeDiscriminator"/> class.
22+
/// The KeyValueTypeDiscriminator will check the target key specified, and if it's value is contained within the
23+
/// type mapping dictionary, the coresponding type will be discriminated.
24+
/// </summary>
25+
/// <param name="baseType">The base type which all discriminated types will implement. Use object if you're discriminating
26+
/// unrelated types. Note the less specific you are with the base type the more yaml will need to be buffered.</param>
27+
/// <param name="targetKey">The known key to check the value of when discriminating.</param>
28+
/// <param name="typeMapping">A mapping dictionary of string to types.</param>
29+
/// <exception cref="ArgumentOutOfRangeException">If any of the target types do not implement the base type.</exception>
1630
public KeyValueTypeDiscriminator(Type baseType, string targetKey, IDictionary<string, Type> typeMapping)
1731
{
18-
1932
foreach (var keyValuePair in typeMapping)
2033
{
2134
if (!baseType.IsAssignableFrom(keyValuePair.Value))
@@ -28,6 +41,17 @@ public KeyValueTypeDiscriminator(Type baseType, string targetKey, IDictionary<st
2841
this.typeMapping = typeMapping;
2942
}
3043

44+
/// <summary>
45+
/// Checks if the current parser contains the target key, and that it's value matches one of the type mappings.
46+
/// If so, return true, and the matching type.
47+
/// Otherwise, return false.
48+
/// This will consume the parser, so you will usually need the parser to be a buffer so an instance
49+
/// of the discriminated type can be deserialized later.
50+
/// </summary>
51+
/// <param name="parser">The IParser to consume and discriminate a type from.</param>
52+
/// <param name="suggestedType">The output type discriminated. Null if there target key was not present of if the value
53+
/// of the target key was not within the type mapping.</param>
54+
/// <returns>Returns true if the discriminator matched the yaml stream.</returns>
3155
public bool TryDiscriminate(IParser parser, out Type? suggestedType)
3256
{
3357
if (parser.TryFindMappingEntry(
@@ -36,32 +60,16 @@ public bool TryDiscriminate(IParser parser, out Type? suggestedType)
3660
out ParsingEvent? value))
3761
{
3862
// read the value of the discriminator key
39-
if (value is Scalar valueScalar)
63+
if (value is Scalar valueScalar && typeMapping.TryGetValue(valueScalar.Value, out var childType))
4064
{
41-
suggestedType = CheckName(valueScalar.Value);
65+
suggestedType = childType;
4266
return true;
4367
}
44-
else
45-
{
46-
throw new Exception($"Could not determine {BaseType} to deserialize to, {targetKey} has an empty value");
47-
}
4868
}
4969

5070
// we could not find our key, thus we could not determine correct child type
5171
suggestedType = null;
5272
return false;
5373
}
54-
55-
private Type CheckName(string value)
56-
{
57-
if (typeMapping.TryGetValue(value, out var childType))
58-
{
59-
return childType;
60-
}
61-
62-
var known = string.Join(",", typeMapping.Keys.ToArray());
63-
64-
throw new Exception($"Could not determine {BaseType} to deserialize to, expecting '{targetKey}' to be one of: {known}, but got '{value}'");
65-
}
6674
}
6775
}

0 commit comments

Comments
 (0)