1
0
Files
named-binary-tag/Nbt/Tag/NbtCompound.cs
2024-03-15 14:44:21 +01:00

118 lines
4.2 KiB
C#
Executable File

using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace Nbt.Tag;
public interface INbtCompound : INbtTag, IEnumerable<NamedTag>
{
int Count { get; }
new INbtTag this[string tagName] { get; set; }
void Add(NamedTag namedTag);
void Add(string tagName, INbtTag tag);
void Set(NamedTag namedTag);
void Set(string tagName, INbtTag tag);
INbtTag Get(string tagName);
T Get<T>(string tagName) where T : INbtTag;
bool TryGet(string tagName, [MaybeNullWhen(false)] out INbtTag tag);
bool TryGet<T>(string tagName, [MaybeNullWhen(false)] out T tag) where T : INbtTag;
bool ContainsKey(string tagName);
bool Contains(NamedTag namedTag);
bool Contains(string tagName, INbtTag tag);
bool Remove(string tagName);
bool Remove(NamedTag namedTag);
bool Remove(string tagName, INbtTag tag);
bool Remove(string tagName, [MaybeNullWhen(false)] out INbtTag tag);
void Clear();
}
public class NbtCompound : INbtCompound
{
private readonly Dictionary<string, INbtTag> entries = [];
private static string EnsureName(string tagName) => tagName ?? throw new ArgumentNullException(nameof(tagName));
private static INbtTag EnsureValue(INbtTag tag) => tag ?? throw new ArgumentNullException(nameof(tag));
public NbtTagType Type => NbtTagType.Compound;
INbtCompound INbtTag.AsCompound() => this;
INbtTag INbtTag.Copy() => Copy();
public NbtCompound Copy()
{
var copy = new NbtCompound();
foreach (var e in entries)
{
copy.entries[e.Key] = e.Value.Copy();
}
return copy;
}
public int Count => entries.Count;
public INbtTag this[string tagName]
{
get => entries[tagName];
set => entries[EnsureName(tagName)] = EnsureValue(value);
}
INbtTag INbtTag.this[INbtPathElement tagPath]
{
get => tagPath is NbtName tagName ? this[tagName] : throw new UnsupportedPathElementException();
set => this[tagPath is NbtName tagName ? tagName : throw new UnsupportedPathElementException()] = value;
}
public void Add(NamedTag namedTag) => Add(namedTag.Name, namedTag.Tag);
public void Add(string tagName, INbtTag tag) => entries.Add(EnsureName(tagName), EnsureValue(tag));
public void Set(NamedTag namedTag) => Set(namedTag.Name, namedTag.Tag);
public void Set(string tagName, INbtTag tag) => this[tagName] = tag;
public INbtTag Get(string tagName) => this[tagName];
public T Get<T>(string tagName) where T : INbtTag => (T)Get(tagName);
public bool TryGet(string tagName, [MaybeNullWhen(false)] out INbtTag tag) => entries.TryGetValue(tagName, out tag);
public bool TryGet<T>(string tagName, [MaybeNullWhen(false)] out T tag) where T : INbtTag
{
if (TryGet(tagName, out var t))
{
tag = (T)t;
return true;
}
tag = default;
return false;
}
public bool ContainsKey(string tagName) => entries.ContainsKey(tagName);
public bool Contains(NamedTag namedTag) => Contains(namedTag.Name, namedTag.Tag);
public bool Contains(string tagName, INbtTag tag) => entries.Contains(KeyValuePair.Create(tagName, tag));
public bool Remove(string tagName) => entries.Remove(tagName);
public bool Remove(NamedTag namedTag) => Remove(namedTag.Name, namedTag.Tag);
public bool Remove(string tagName, INbtTag tag) => ((IDictionary<string, INbtTag>)entries).Remove(KeyValuePair.Create(tagName, tag));
public bool Remove(string tagName, [MaybeNullWhen(false)] out INbtTag tag) => entries.Remove(tagName, out tag);
public void Clear() => entries.Clear();
public bool Equals(INbtTag? other) => ReferenceEquals(other, this) || other is NbtCompound o && Utils.DictionaryEquals(entries, o.entries);
public override bool Equals(object? obj) => ReferenceEquals(obj, this) || obj is INbtCompound other && Equals(other);
public override int GetHashCode() => entries.GetHashCode();
public IEnumerator<NamedTag> GetEnumerator() => entries.Select(e => new NamedTag(e.Key, e.Value)).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)entries).GetEnumerator();
}