2using System.Collections.Immutable;
13 internal class Manifest
16 static readonly
char[] ManifestNameValueSeparatorChars = [
':'];
18 readonly ImmutableDictionary<string, string> _mainAttributes;
19 readonly ImmutableDictionary<string, ImmutableDictionary<string, string>> _attributes;
25 public Manifest(TextReader reader)
27 var attributes = ImmutableDictionary.CreateBuilder<string, ImmutableDictionary<string, string>>();
30 while (ReadSection(reader) is { } section)
32 if (_mainAttributes is
null)
34 section = section.Remove(
"Name");
35 _mainAttributes = section;
39 if (section.TryGetValue(
"Name", out var name))
41 section = section.Remove(
"Name");
42 attributes[name] = section;
46 throw new FormatException(
"Non-main manifest section missing Name attribute.");
51 if (_mainAttributes is
null)
52 throw new FormatException(
"Could not find main manifest section.");
55 _attributes = attributes.ToImmutable();
62 public Manifest(Stream stream) :
63 this(new StreamReader(stream))
72 public Manifest(
string value) :
73 this(new StringReader(value))
82 ImmutableDictionary<string, string>? ReadSection(TextReader reader)
84 var attributes = ImmutableDictionary.CreateBuilder<string,
string>(StringComparer.OrdinalIgnoreCase);
87 while (reader.ReadLine() is
string s && s.Trim() !=
"")
88 if (s.Split(ManifestNameValueSeparatorChars, 2) is
string[] p && p.Length == 2)
89 attributes[p[0].Trim()] = p[1].Trim();
92 return attributes.Count > 0 ? attributes.ToImmutable() :
null;
98 public ImmutableDictionary<string, string> MainAttributes => _mainAttributes;
103 public ImmutableDictionary<string, ImmutableDictionary<string, string>> Attributes => _attributes;