@@ -27,7 +27,7 @@ public class AbbreviatedUnitsConverter : JsonConverter<IQuantity>
27
27
private const string TypeProperty = "Type" ;
28
28
29
29
private readonly UnitAbbreviationsCache _abbreviations ;
30
- private readonly IEqualityComparer < string > _propertyComparer ;
30
+ private readonly IEqualityComparer < string ? > _propertyComparer ;
31
31
private readonly IDictionary < string , QuantityInfo > _quantities ;
32
32
private readonly UnitParser _unitParser ;
33
33
@@ -43,7 +43,7 @@ public AbbreviatedUnitsConverter()
43
43
/// Construct a converter using the default list of quantities and unit abbreviation provider
44
44
/// </summary>
45
45
/// <param name="comparer">The comparer used to compare the property/quantity names (e.g. StringComparer.OrdinalIgnoreCase) </param>
46
- public AbbreviatedUnitsConverter ( IEqualityComparer < string > comparer )
46
+ public AbbreviatedUnitsConverter ( IEqualityComparer < string ? > comparer )
47
47
: this ( new Dictionary < string , QuantityInfo > ( Quantity . ByName , comparer ) , UnitAbbreviationsCache . Default , comparer )
48
48
{
49
49
}
@@ -54,7 +54,7 @@ public AbbreviatedUnitsConverter(IEqualityComparer<string> comparer)
54
54
/// <param name="quantities">The dictionary of quantity names</param>
55
55
/// <param name="abbreviations">The unit abbreviations used for the serialization </param>
56
56
/// <param name="propertyComparer">The comparer used to compare the property names (e.g. StringComparer.OrdinalIgnoreCase) </param>
57
- public AbbreviatedUnitsConverter ( IDictionary < string , QuantityInfo > quantities , UnitAbbreviationsCache abbreviations , IEqualityComparer < string > propertyComparer )
57
+ public AbbreviatedUnitsConverter ( IDictionary < string , QuantityInfo > quantities , UnitAbbreviationsCache abbreviations , IEqualityComparer < string ? > propertyComparer )
58
58
{
59
59
_quantities = quantities ;
60
60
_abbreviations = abbreviations ;
@@ -63,7 +63,7 @@ public AbbreviatedUnitsConverter(IDictionary<string, QuantityInfo> quantities, U
63
63
}
64
64
65
65
/// <inheritdoc />
66
- public override void WriteJson ( JsonWriter writer , IQuantity quantity , JsonSerializer serializer )
66
+ public override void WriteJson ( JsonWriter writer , IQuantity ? quantity , JsonSerializer serializer )
67
67
{
68
68
if ( quantity is null )
69
69
{
@@ -110,17 +110,16 @@ protected string GetQuantityType(IQuantity quantity)
110
110
}
111
111
112
112
/// <inheritdoc />
113
- public override IQuantity ReadJson ( JsonReader reader , Type objectType , IQuantity existingValue , bool hasExistingValue , JsonSerializer serializer )
113
+ public override IQuantity ? ReadJson ( JsonReader reader , Type objectType , IQuantity ? existingValue , bool hasExistingValue , JsonSerializer serializer )
114
114
{
115
- QuantityInfo quantityInfo ;
115
+ QuantityInfo ? quantityInfo ;
116
116
if ( reader . TokenType == JsonToken . Null )
117
117
{
118
- // return null;
119
118
return TryGetQuantity ( objectType . Name , out quantityInfo ) ? quantityInfo . Zero : default ;
120
119
}
121
120
122
- string valueToken = null ;
123
- string unitAbbreviation = null , quantityName = null ;
121
+ string ? valueToken = null ;
122
+ string ? unitAbbreviation = null , quantityName = null ;
124
123
if ( reader . TokenType == JsonToken . StartObject )
125
124
{
126
125
while ( reader . Read ( ) && reader . TokenType != JsonToken . EndObject )
@@ -148,18 +147,23 @@ public override IQuantity ReadJson(JsonReader reader, Type objectType, IQuantity
148
147
}
149
148
}
150
149
150
+
151
151
Enum unit ;
152
152
if ( quantityName is null )
153
153
{
154
154
if ( TryGetQuantity ( objectType . Name , out quantityInfo ) )
155
155
{
156
156
unit = GetUnitOrDefault ( unitAbbreviation , quantityInfo ) ;
157
157
}
158
- else // the objectType doesn't match any concrete quantity type (likely it is an IQuantity)
158
+ else if ( unitAbbreviation != null ) // the objectType doesn't match any concrete quantity type (likely it is an IQuantity)
159
159
{
160
160
// failing back to an exhaustive search (it is possible that this converter was created with a short-list of non-ambiguous quantities
161
161
unit = FindUnit ( unitAbbreviation , out quantityInfo ) ;
162
162
}
163
+ else
164
+ {
165
+ throw new FormatException ( "No unit abbreviation found in JSON." ) ;
166
+ }
163
167
}
164
168
else
165
169
{
@@ -203,8 +207,8 @@ protected virtual Enum FindUnit(string unitAbbreviation, out QuantityInfo quanti
203
207
throw new UnitNotFoundException ( "The unit abbreviation and quantity type cannot both be null" ) ;
204
208
}
205
209
206
- Enum unit = null ;
207
- quantityInfo = default ;
210
+ Enum ? unit = null ;
211
+ QuantityInfo ? tempQuantityInfo = default ;
208
212
foreach ( var targetQuantity in _quantities . Values )
209
213
{
210
214
if ( ! TryParse ( unitAbbreviation , targetQuantity , out var unitMatched ) )
@@ -213,20 +217,21 @@ protected virtual Enum FindUnit(string unitAbbreviation, out QuantityInfo quanti
213
217
}
214
218
215
219
if ( unit != null &&
216
- ! ( targetQuantity == quantityInfo && Equals ( unit , unitMatched ) ) ) // it is possible to have "synonyms": e.g. "Mass" and "Weight"
220
+ ! ( targetQuantity == tempQuantityInfo && Equals ( unit , unitMatched ) ) ) // it is possible to have "synonyms": e.g. "Mass" and "Weight"
217
221
{
218
222
throw new AmbiguousUnitParseException ( $ "Multiple quantities found matching the provided abbreviation: { unit } , { unitMatched } ") ;
219
223
}
220
224
221
- quantityInfo = targetQuantity ;
225
+ tempQuantityInfo = targetQuantity ;
222
226
unit = unitMatched ;
223
227
}
224
228
225
- if ( unit is null )
229
+ if ( unit is null || tempQuantityInfo is null )
226
230
{
227
231
throw new UnitNotFoundException ( $ "No quantity found with abbreviation [{ unitAbbreviation } ].") ;
228
232
}
229
233
234
+ quantityInfo = tempQuantityInfo ;
230
235
return unit ;
231
236
}
232
237
@@ -254,7 +259,7 @@ protected string GetUnitAbbreviation(Enum unit)
254
259
/// <returns>Unit enum value, such as <see cref="MassUnit.Kilogram" />.</returns>
255
260
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
256
261
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
257
- protected virtual Enum GetUnitOrDefault ( string unitAbbreviation , QuantityInfo quantityInfo )
262
+ protected virtual Enum GetUnitOrDefault ( string ? unitAbbreviation , QuantityInfo quantityInfo )
258
263
{
259
264
return unitAbbreviation == null
260
265
? quantityInfo . BaseUnitInfo . Value
@@ -269,7 +274,7 @@ protected virtual Enum GetUnitOrDefault(string unitAbbreviation, QuantityInfo qu
269
274
/// <returns>Unit enum value, such as <see cref="MassUnit.Kilogram" />.</returns>
270
275
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
271
276
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
272
- protected Enum Parse ( string unitAbbreviation , QuantityInfo quantityInfo )
277
+ protected Enum Parse ( string ? unitAbbreviation , QuantityInfo quantityInfo )
273
278
{
274
279
return _unitParser . Parse ( unitAbbreviation , quantityInfo . UnitType , CultureInfo . InvariantCulture ) ;
275
280
}
@@ -283,7 +288,7 @@ protected Enum Parse(string unitAbbreviation, QuantityInfo quantityInfo)
283
288
/// <returns>True if successful.</returns>
284
289
/// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception>
285
290
/// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception>
286
- protected bool TryParse ( string unitAbbreviation , QuantityInfo quantityInfo , out Enum unit )
291
+ protected bool TryParse ( string ? unitAbbreviation , QuantityInfo quantityInfo , out Enum ? unit )
287
292
{
288
293
return _unitParser . TryParse ( unitAbbreviation , quantityInfo . UnitType , CultureInfo . InvariantCulture , out unit ) ;
289
294
}
0 commit comments