fix: Do not parse NULL into empty collections

When you specify an empty object in YAML, like:

```
quality_profiles:
```

This causes that respective object/collection to be assigned `null`.
YamlDotNet feature request covering this behavior can be found
[here][1].

Fixes #89.

[1]: https://github.com/aaubry/YamlDotNet/issues/443
pull/92/head
Robert Dailey 3 years ago
parent 0d20924ee3
commit b41ed72283

@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Do not exit when a YAML config has no sonarr or radarr section.
- Sonarr: Invalid release profile JSON files no longer cause the program to exit. Instead, it just
skips them and prints a warning to the user. (#87)
- Radarr: Do not crash when `quality_profiles` is empty. (#89)
## [2.2.0] - 2022-06-03

@ -0,0 +1,55 @@
using System.Collections;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
namespace Common.YamlDotNet;
// Borrowed from: https://github.com/aaubry/YamlDotNet/issues/443#issuecomment-544449498
public sealed class ForceEmptySequences : INodeDeserializer
{
private readonly IObjectFactory _objectFactory;
public ForceEmptySequences(IObjectFactory objectFactory)
{
_objectFactory = objectFactory;
}
public bool Deserialize(IParser reader, Type expectedType, Func<IParser, Type, object?> nestedObjectDeserializer,
out object? value)
{
value = null;
if (!IsEnumerable(expectedType) || !reader.Accept<NodeEvent>(out var evt) || !NodeIsNull(evt))
{
return false;
}
reader.SkipThisAndNestedEvents();
value = _objectFactory.Create(expectedType);
return true;
}
private static bool NodeIsNull(NodeEvent nodeEvent)
{
// http://yaml.org/type/null.html
if (nodeEvent.Tag == "tag:yaml.org,2002:null")
{
return true;
}
if (nodeEvent is not Scalar {Style: ScalarStyle.Plain} scalar)
{
return false;
}
var value = scalar.Value;
return value is "" or "~" or "null" or "Null" or "NULL";
}
private static bool IsEnumerable(Type type)
{
return typeof(IEnumerable).IsAssignableFrom(type);
}
}

@ -19,6 +19,7 @@ public class YamlSerializerFactory : IYamlSerializerFactory
.WithNamingConvention(UnderscoredNamingConvention.Instance)
.WithTypeConverter(new YamlNullableEnumTypeConverter())
.WithNodeTypeResolver(new ReadOnlyCollectionNodeTypeResolver())
.WithNodeDeserializer(new ForceEmptySequences(_objectFactory))
.WithObjectFactory(_objectFactory)
.Build();
}

Loading…
Cancel
Save