// src/GeoVLog.Core/Manifests/FlightManifestYamlSerializer.cs using System.IO; using System.Text; using System.Threading.Tasks; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; namespace GeoVLog.Core.Manifests; /// /// Serialises / deserialises to YAML 1.2 /// using YamlDotNet. /// – Camel-case keys
/// – Null values are omitted (all other defaults are kept so the YAML /// stays informative when a numeric 0 or an empty list is intentional). ///
public sealed class FlightManifestYamlSerializer : IFlightManifestSerializer { /* ------------------------------------------------------------------ */ /* Writers / readers are expensive to build; keep one static copy. */ /* ------------------------------------------------------------------ */ private static readonly ISerializer _yamlWriter = new SerializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull) .Build(); private static readonly IDeserializer _yamlReader = new DeserializerBuilder() .WithNamingConvention(CamelCaseNamingConvention.Instance) .IgnoreUnmatchedProperties() .Build(); /* ------------------------------------------------------------------ */ /* IFlightManifestSerializer */ /* ------------------------------------------------------------------ */ public async Task SerializeAsync(FlightManifest manifest, Stream output) { string yaml = _yamlWriter.Serialize(manifest); byte[] bytes = Encoding.UTF8.GetBytes(yaml); await output.WriteAsync(bytes); } public async Task DeserializeAsync(Stream input) { using var sr = new StreamReader(input, Encoding.UTF8, leaveOpen: true); string yaml = await sr.ReadToEndAsync(); return _yamlReader.Deserialize(yaml); } }