Initial sync
This commit is contained in:
139
Nbt/NbtPath.cs
Executable file
139
Nbt/NbtPath.cs
Executable file
@@ -0,0 +1,139 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace Nbt;
|
||||
|
||||
public static class NbtPath
|
||||
{
|
||||
public static readonly INbtPath Empty = new EmptyNbtPathImpl();
|
||||
|
||||
public static INbtPath CreatePath(INbtPathElement pathElement) => new NbtPathImpl([pathElement]);
|
||||
|
||||
public static INbtPath CreatePath(params INbtPathElement[] pathElements) => CreatePath(pathElements.AsEnumerable());
|
||||
|
||||
public static INbtPath CreatePath(IEnumerable<INbtPathElement> pathElements) => new NbtPathImpl(pathElements);
|
||||
|
||||
public static INbtPath CreatePath(params object[] pathElements) => CreatePath(pathElements.AsEnumerable());
|
||||
|
||||
public static INbtPath CreatePath(IEnumerable<object> pathElements) => CreatePath(pathElements.Select(WrapPathElement));
|
||||
|
||||
private static INbtPathElement WrapPathElement(object pathElement) => pathElement switch
|
||||
{
|
||||
null => throw new ArgumentNullException(nameof(pathElement)),
|
||||
string name => new NbtName(name),
|
||||
int index => new NbtIndex(index),
|
||||
_ => throw new ArgumentException($"Invalid path element type: {pathElement.GetType().Name}", nameof(pathElement))
|
||||
};
|
||||
}
|
||||
|
||||
public interface INbtPath : IEnumerable<INbtPathElement>
|
||||
{
|
||||
int Count { get; }
|
||||
|
||||
bool IsEmpty { get; }
|
||||
|
||||
INbtPathElement PopFirst(out INbtPath rest);
|
||||
|
||||
INbtPathElement this[int index] { get; }
|
||||
|
||||
INbtPath Combine(INbtPath other);
|
||||
|
||||
INbtPath Append(INbtPathElement pathElement);
|
||||
|
||||
INbtPath Insert(int index, INbtPathElement pathElement);
|
||||
|
||||
INbtPath Replace(int index, INbtPathElement pathElement);
|
||||
}
|
||||
|
||||
file class NbtPathImpl(IEnumerable<INbtPathElement> pathElements) : INbtPath
|
||||
{
|
||||
private readonly IList<INbtPathElement> _pathElements = pathElements.AsIList();
|
||||
|
||||
public int Count => _pathElements.Count;
|
||||
|
||||
public bool IsEmpty => Count == 0;
|
||||
|
||||
public INbtPathElement PopFirst(out INbtPath rest)
|
||||
{
|
||||
var count = Count;
|
||||
|
||||
if (count < 1)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
rest = count > 1 ? new NbtPathImpl(_pathElements.Skip(1)) : NbtPath.Empty;
|
||||
return _pathElements[0];
|
||||
}
|
||||
|
||||
public INbtPathElement this[int index] => _pathElements[index];
|
||||
|
||||
public INbtPath Append(INbtPathElement pathElement) => new NbtPathImpl(_pathElements.Append(pathElement));
|
||||
|
||||
public INbtPath Insert(int index, INbtPathElement pathElement) => new NbtPathImpl(Utils.Insert(_pathElements, index, pathElement));
|
||||
|
||||
public INbtPath Replace(int index, INbtPathElement pathElement) => new NbtPathImpl(Utils.Replace(_pathElements, index, pathElement));
|
||||
|
||||
public INbtPath Combine(INbtPath other) => new NbtPathImpl(_pathElements.Concat(other));
|
||||
|
||||
public IEnumerator<INbtPathElement> GetEnumerator() => _pathElements.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
|
||||
file class EmptyNbtPathImpl : INbtPath
|
||||
{
|
||||
public int Count => 0;
|
||||
|
||||
public bool IsEmpty => true;
|
||||
|
||||
public INbtPathElement PopFirst(out INbtPath rest) => throw new IndexOutOfRangeException();
|
||||
|
||||
public INbtPathElement this[int index] => throw new IndexOutOfRangeException();
|
||||
|
||||
public INbtPath Append(INbtPathElement pathElement) => new NbtPathImpl(pathElement.Yield());
|
||||
|
||||
public INbtPath Insert(int index, INbtPathElement pathElement)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNotEqual(index, 0);
|
||||
|
||||
return new NbtPathImpl(pathElement.Yield());
|
||||
}
|
||||
|
||||
public INbtPath Replace(int index, INbtPathElement pathElement)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
}
|
||||
|
||||
public INbtPath Combine(INbtPath other) => other;
|
||||
|
||||
public IEnumerator<INbtPathElement> GetEnumerator() => Enumerable.Empty<INbtPathElement>().GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
|
||||
public interface INbtPathElement
|
||||
{
|
||||
object Key { get; }
|
||||
}
|
||||
|
||||
public readonly struct NbtName(string name) : INbtPathElement
|
||||
{
|
||||
public string Name { get; } = name;
|
||||
|
||||
object INbtPathElement.Key => Name;
|
||||
|
||||
public static implicit operator NbtName(string tagName) => new(tagName);
|
||||
|
||||
public static implicit operator string(NbtName nbtName) => nbtName.Name;
|
||||
}
|
||||
|
||||
public readonly struct NbtIndex(int index) : INbtPathElement
|
||||
{
|
||||
public int Index { get; } = index;
|
||||
|
||||
object INbtPathElement.Key => Index;
|
||||
|
||||
public static implicit operator NbtIndex(int tagIndex) => new(tagIndex);
|
||||
|
||||
public static implicit operator int(NbtIndex nbtIndex) => nbtIndex.Index;
|
||||
}
|
||||
Reference in New Issue
Block a user