JsonPathReader
                    struct JsonPathReader
                
                Reads a JsonPath expression and breaks it into tokens for processing.
            Follows RFC 9535 minus the filter expressions and wildcards, which are not supported in this implementation.
            
                using System.Runtime.CompilerServices;
using System.Text;
namespace System.ClientModel.Primitives
{
    internal ref struct JsonPathReader
    {
        private ref struct PeekedJsonPathToken
        {
            public JsonPathToken Token;
            public bool HasValue;
            public int Consumed;
        }
        private const byte DollarSign = 36;
        private const byte Dot = 46;
        private const byte OpenBracket = 91;
        private const byte CloseBracket = 93;
        private const byte SingleQuote = 39;
        private const byte DoubleQuote = 34;
        private const byte Zero = 48;
        private const byte Nine = 57;
        private readonly ReadOnlySpan<byte> _jsonPath;
        private int _consumed;
        private int _length;
        private PeekedJsonPathToken _peeked;
        public JsonPathToken Current {
            [System.Runtime.CompilerServices.IsReadOnly]
            get;
            private set;
        }
        [System.Runtime.CompilerServices.NullableContext(1)]
        public JsonPathReader(string jsonPath)
        {
            this = new JsonPathReader(Encoding.UTF8.GetBytes(jsonPath).AsSpan());
        }
        public JsonPathReader(ReadOnlySpan<byte> jsonPath)
        {
            _peeked = default(PeekedJsonPathToken);
            Current = default(JsonPathToken);
            _jsonPath = jsonPath;
            _consumed = 0;
            _length = jsonPath.Length;
        }
        public bool Read()
        {
            if (_peeked.HasValue) {
                Current = _peeked.Token;
                _consumed = _peeked.Consumed;
                _peeked.HasValue = false;
                return true;
            }
            JsonPathToken current = Current;
            if (current.TokenType == JsonPathTokenType.End)
                return false;
            if (_consumed < _length) {
                switch (_jsonPath[_consumed]) {
                case 36: {
                    ReadOnlySpan<byte> valueSpan = _jsonPath.Slice(_consumed, 1);
                    Current = new JsonPathToken(JsonPathTokenType.Root, _consumed++, valueSpan);
                    return true;
                }
                case 46:
                    Current = new JsonPathToken(JsonPathTokenType.PropertySeparator, _consumed++, default(ReadOnlySpan<byte>));
                    return true;
                case 91: {
                    if (_consumed + 1 >= _length)
                        throw new FormatException($"""{_consumed + 1}""");
                    byte b = _jsonPath[_consumed + 1];
                    if (b == 39 || b == 34) {
                        Current = new JsonPathToken(JsonPathTokenType.PropertySeparator, _consumed++, default(ReadOnlySpan<byte>));
                        return true;
                    }
                    if (!IsDigit(b))
                        throw new FormatException($"""{_consumed + 1}""");
                    _consumed++;
                    Current = ReadNumber();
                    if (_consumed >= _length || _jsonPath[_consumed] != 93)
                        throw new FormatException($"""{_consumed}""");
                    _consumed++;
                    return true;
                }
                case 34:
                case 39:
                    current = Current;
                    if (current.TokenType == JsonPathTokenType.PropertySeparator && _jsonPath[_consumed - 1] == 46)
                        Current = ReadProperty();
                    else {
                        Current = ReadQuotedString();
                        if (_consumed >= _length || _jsonPath[_consumed] != 93)
                            throw new FormatException($"""{_consumed}""");
                        _consumed++;
                    }
                    return true;
                default:
                    Current = ReadProperty();
                    return true;
                }
            }
            Current = new JsonPathToken(JsonPathTokenType.End, _length - 1, default(ReadOnlySpan<byte>));
            return true;
        }
        public JsonPathToken Peek()
        {
            if (Current.TokenType == JsonPathTokenType.End)
                return Current;
            if (_peeked.HasValue)
                return _peeked.Token;
            JsonPathReader jsonPathReader = this;
            jsonPathReader.Read();
            _peeked.HasValue = true;
            _peeked.Consumed = jsonPathReader._consumed;
            _peeked.Token = jsonPathReader.Current;
            return _peeked.Token;
        }
        public ReadOnlySpan<byte> GetFirstProperty()
        {
            if (_jsonPath.IsRoot())
                return _jsonPath;
            if (!Read())
                return ReadOnlySpan<byte>.Empty;
            JsonPathToken current = Current;
            if (current.TokenType != 0)
                return ReadOnlySpan<byte>.Empty;
            if (!Read())
                return ReadOnlySpan<byte>.Empty;
            current = Current;
            if (current.TokenType != JsonPathTokenType.PropertySeparator || Read()) {
                current = Current;
                switch (current.TokenType) {
                case JsonPathTokenType.Property:
                    return _jsonPath.Slice(0, _consumed);
                case JsonPathTokenType.ArrayIndex:
                    return _jsonPath.Slice(0, _consumed);
                default:
                    return ReadOnlySpan<byte>.Empty;
                }
            }
            return ReadOnlySpan<byte>.Empty;
        }
        public ReadOnlySpan<byte> GetNextArray()
        {
            while (Read()) {
                if (Current.TokenType == JsonPathTokenType.ArrayIndex)
                    return _jsonPath.Slice(0, _consumed);
            }
            return ReadOnlySpan<byte>.Empty;
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private JsonPathToken ReadQuotedString()
        {
            ReadOnlySpan<byte> jsonPath = _jsonPath;
            byte b = jsonPath[_consumed];
            int num = ++_consumed;
            while (_consumed < _length && (jsonPath[_consumed] != b || _consumed + 1 >= _length || jsonPath[_consumed + 1] != 93)) {
                _consumed++;
            }
            if (_consumed >= _length)
                throw new FormatException("Unterminated quoted string in JsonPath");
            ReadOnlySpan<byte> valueSpan = jsonPath.Slice(num, _consumed - num);
            _consumed++;
            return new JsonPathToken(JsonPathTokenType.Property, num, valueSpan);
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private JsonPathToken ReadNumber()
        {
            ReadOnlySpan<byte> jsonPath = _jsonPath;
            int consumed = _consumed;
            while (_consumed < _length && IsDigit(jsonPath[_consumed])) {
                _consumed++;
            }
            return new JsonPathToken(JsonPathTokenType.ArrayIndex, consumed, jsonPath.Slice(consumed, _consumed - consumed));
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private JsonPathToken ReadProperty()
        {
            ReadOnlySpan<byte> jsonPath = _jsonPath;
            int consumed = _consumed;
            while (_consumed < _length) {
                byte b = jsonPath[_consumed];
                if (b == 46 || b == 91 || b == 93)
                    break;
                _consumed++;
            }
            return new JsonPathToken(JsonPathTokenType.Property, consumed, jsonPath.Slice(consumed, _consumed - consumed));
        }
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        internal static bool IsDigit(byte b)
        {
            if (b >= 48)
                return b <= 57;
            return false;
        }
        public bool Advance(ReadOnlySpan<byte> prefix)
        {
            if (prefix.IsEmpty || _jsonPath.IsEmpty)
                return false;
            if (prefix.Length >= _length)
                return false;
            if (_jsonPath.StartsWith(prefix)) {
                _consumed = prefix.Length;
                return true;
            }
            if (prefix[0] != 36 || _jsonPath[0] != 36)
                return false;
            JsonPathReader jsonPathReader = new JsonPathReader(prefix);
            JsonPathToken current;
            while (Read() && jsonPathReader.Read()) {
                current = Current;
                ReadOnlySpan<byte> valueSpan = current.ValueSpan;
                current = jsonPathReader.Current;
                if (!valueSpan.SequenceEqual(current.ValueSpan))
                    return false;
            }
            current = jsonPathReader.Current;
            if (current.TokenType == JsonPathTokenType.End) {
                current = Current;
                return current.TokenType != JsonPathTokenType.End;
            }
            return false;
        }
        internal ReadOnlySpan<byte> GetParsedPath()
        {
            if (_consumed == 0)
                return ReadOnlySpan<byte>.Empty;
            return _jsonPath.Slice(0, _consumed);
        }
        public bool Equals(JsonPathReader other)
        {
            return JsonPathComparer.Default.NormalizedEquals(_jsonPath, other._jsonPath);
        }
        public override int GetHashCode()
        {
            return JsonPathComparer.Default.GetNormalizedHashCode(_jsonPath);
        }
    }
}