Example #1
0
        public static PathInfo Parse(string path)
        {
            if (path == "null")
            {
                return(Empty);
            }

            var originalPath  = path;
            var pathType      = GetPathType(path);
            var pathSubstring = new Substring(path);

            var isValidHelperLiteral = true;
            var isVariable           = pathType == PathType.Variable;
            var isInversion          = pathType == PathType.Inversion;
            var isBlockHelper        = pathType == PathType.BlockHelper;

            if (isVariable || isBlockHelper || isInversion)
            {
                isValidHelperLiteral = isBlockHelper || isInversion;
                pathSubstring        = new Substring(pathSubstring, 1);
            }

            var segments           = new List <PathSegment>();
            var pathParts          = Substring.Split(pathSubstring, '/');
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts);

            while (extendedEnumerator.MoveNext())
            {
                var segment = extendedEnumerator.Current.Value;
                if (segment.Length == 2 && segment[0] == '.' && segment[1] == '.')
                {
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                if (segment.Length == 1 && segment[0] == '.')
                {
                    isValidHelperLiteral = false;
                    segments.Add(new PathSegment(segment, ArrayEx.Empty <ChainSegment>()));
                    continue;
                }

                var chainSegments = GetPathChain(segment);
                if (chainSegments.Length > 1)
                {
                    isValidHelperLiteral = false;
                }

                segments.Add(new PathSegment(segment, chainSegments));
            }

            if (isValidHelperLiteral && segments.Count > 1)
            {
                isValidHelperLiteral = false;
            }

            return(new PathInfo(pathType, originalPath, isValidHelperLiteral, segments.ToArray()));
        }
Example #2
0
        private static ChainSegment[] GetPathChain(Substring segmentString)
        {
            var insideEscapeBlock  = false;
            var pathChainParts     = Substring.Split(segmentString, '.', StringSplitOptions.RemoveEmptyEntries);
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathChainParts);

            if (!extendedEnumerator.Any && segmentString == ".")
            {
                return new[] { ChainSegment.This }
            }
            ;

            var chainSegments = new List <ChainSegment>();

            while (extendedEnumerator.MoveNext())
            {
                var next = extendedEnumerator.Current.Value;

                if (insideEscapeBlock)
                {
                    if (next.EndsWith(']'))
                    {
                        insideEscapeBlock = false;
                    }

                    chainSegments[chainSegments.Count - 1] = ChainSegment.Create($"{chainSegments[chainSegments.Count - 1]}.{next.ToString()}");
                    continue;
                }

                if (next.StartsWith('['))
                {
                    insideEscapeBlock = true;
                }

                if (next.EndsWith(']'))
                {
                    insideEscapeBlock = false;
                }

                chainSegments.Add(ChainSegment.Create(next.ToString()));
            }

            return(chainSegments.ToArray());
        }
Example #3
0
        public static PathInfo Parse(string path)
        {
            if (path == "null")
            {
                return(Empty);
            }

            var originalPath  = path;
            var pathType      = GetPathType(path);
            var pathSubstring = new Substring(path);

            var isValidHelperLiteral = true;
            var isVariable           = pathType == PathType.Variable;
            var isInversion          = pathType == PathType.Inversion;
            var isBlockHelper        = pathType == PathType.BlockHelper;

            if (isVariable || isBlockHelper || isInversion)
            {
                isValidHelperLiteral = isBlockHelper || isInversion;
                pathSubstring        = new Substring(pathSubstring, 1);
            }

            var segments           = new List <PathSegment>();
            var pathParts          = Substring.Split(pathSubstring, '/');
            var extendedEnumerator = ExtendedEnumerator <Substring> .Create(pathParts);

            using var container = StringBuilderPool.Shared.Use();
            var buffer = container.Value;

            while (extendedEnumerator.MoveNext())
            {
                var segment = extendedEnumerator.Current.Value;
                if (buffer.Length != 0)
                {
                    buffer.Append('/');
                    buffer.Append(in segment);
                    if (Substring.LastIndexOf(segment, ']', out var index) &&
                        !Substring.LastIndexOf(segment, '[', index, out _))
                    {
                        var chainSegment = GetPathChain(buffer.ToString());
                        if (chainSegment.Length > 1)
                        {
                            isValidHelperLiteral = false;
                        }

                        segments.Add(new PathSegment(segment, chainSegment));
                        buffer.Length = 0;
                        continue;
                    }
                }

                if (Substring.LastIndexOf(segment, '[', out var startIndex) &&
                    !Substring.LastIndexOf(segment, ']', startIndex, out _))
                {
                    buffer.Append(in segment);
                    continue;
                }

                switch (segment.Length)
                {
                case 2 when segment[0] == '.' && segment[1] == '.':