Skip to content

Instantly share code, notes, and snippets.

@Aetopia
Created August 27, 2024 18:24
Show Gist options
  • Save Aetopia/36c40c8ee61b7db705b14a3944198b37 to your computer and use it in GitHub Desktop.
Save Aetopia/36c40c8ee61b7db705b14a3944198b37 to your computer and use it in GitHub Desktop.
namespace System.Runtime.Serialization.Json;
using System;
using System.Xml;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Collections;
using System.Collections.Generic;
public sealed class JsonNode :IEnumerable<JsonNode>
{
enum _ { Null, Object, Array, String, Number, Boolean }
readonly XElement Element;
readonly _ Type;
JsonNode(XElement _) => Enum.TryParse((Element = _).Attribute("type").Value, true, out Type);
public static JsonNode Parse(string value)
{
using var _ = JsonReaderWriterFactory.CreateJsonReader(Encoding.Unicode.GetBytes(value), XmlDictionaryReaderQuotas.Max);
return new(XElement.Load(_));
}
public JsonNode this[string key] => new(
Type != _.Object
? throw new InvalidOperationException()
: Element.Elements().First(_ => (_.Name.NamespaceName == string.Empty ? _.Name.LocalName : _.Attribute("item").Value) == key)
);
public JsonNode this[int index] => new(
Type != _.Array
? throw new InvalidOperationException()
: Element.Elements().ElementAt(index)
);
T Value<T>() => Type switch
{
JsonNode._.Null or JsonNode._.Object or JsonNode._.Array => throw new InvalidCastException(),
_ => (T)Convert.ChangeType(Element.Value, typeof(T))
};
public double Number() => Value<double>();
public string String() => Value<string>();
public bool Boolean() => Value<bool>();
public IEnumerator<JsonNode> GetEnumerator() => Element.Elements().Select(_ => new JsonNode(_)).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => null;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment