< Summary

Information
Class: NanoRoute.Internals.RouteNode
Assembly: NanoRoute.dll
File(s): /home/runner/work/nanoroute/nanoroute/Src/NanoRoute/Private/RouteNode.cs
Line coverage
100%
Covered lines: 36
Uncovered lines: 0
Coverable lines: 36
Total lines: 90
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBlocks covered Blocks not covered
RouteNode()60
RouteNode(...)340
Freeze()20

File(s)

/home/runner/work/nanoroute/nanoroute/Src/NanoRoute/Private/RouteNode.cs

#LineLine coverage
 1/********************************************************************************
 2* RouteNode.cs                                                                  *
 3*                                                                               *
 4* Author: Denes Solti                                                           *
 5********************************************************************************/
 6using System;
 7using System.Collections.Frozen;
 8using System.Collections.Generic;
 9using System.Collections.Immutable;
 10using System.Linq;
 11
 12namespace NanoRoute.Internals
 13{
 14    /// <summary>
 15    /// Represents a node in the route tree.
 16    /// </summary>
 17    internal sealed class RouteNode
 18    {
 19        /// <summary>
 20        /// Gets the verb-tagged handlers registered for the current route node.
 21        /// </summary>
 22        public IList<KeyValuePair<HttpVerb, HandlerRegistration>> Handlers { get; }
 23
 24        /// <summary>
 25        /// Gets literal branches keyed by case-insensitive segment value.
 26        /// </summary>
 27        public IDictionary<ReadOnlyMemory<char>, RouteNode> LiteralBranches { get; }
 28
 29        /// <summary>
 30        /// Gets parser-based branches.
 31        /// </summary>
 32        public IList<KeyValuePair<ParameterParser, RouteNode>> ParsedBranches { get; }
 33
 34        /// <summary>
 35        /// Returns true if this node is read-only.
 36        /// </summary>
 37        public bool Frozen { get; }
 38
 39        /// <summary>
 40        /// Gets the only branch reachable from this node when it has no handlers and a single child branch kind.
 41        /// </summary>
 42        public object? SingleBranch { get; }
 43
 244        public RouteNode()
 245        {
 246            Handlers = new List<KeyValuePair<HttpVerb, HandlerRegistration>>();
 247            LiteralBranches = new Dictionary<ReadOnlyMemory<char>, RouteNode>(ReadOnlyMemoryCharComparer.Instance);
 248            ParsedBranches = new List<KeyValuePair<ParameterParser, RouteNode>>();
 249        }
 50
 251        private RouteNode(RouteNode src)
 252        {
 253            LiteralBranches = src.LiteralBranches.ToFrozenDictionary
 254            (
 255                static kvp => kvp.Key,
 256                static kvp => kvp.Value.Freeze(),
 257                ReadOnlyMemoryCharComparer.Instance
 258            );
 59
 260            ParsedBranches = src
 261                .ParsedBranches
 262                .Select
 263                (
 264                    static kvp => new KeyValuePair<ParameterParser, RouteNode>
 265                    (
 266                        kvp.Key,
 267                        kvp.Value.Freeze()
 268                    )
 269                )
 270                .ToImmutableArray();
 71
 272            Handlers = src.Handlers.ToImmutableArray();
 73
 274            if (Handlers.Count is 0)
 275                SingleBranch = (LiteralBranches.Count, ParsedBranches.Count) switch
 276                {
 277                    (1, 0) => LiteralBranches.Single(),
 278                    (0, 1) => ParsedBranches.Single(),
 279                    _ => default
 280                };
 81
 282            Frozen = true;
 283        }
 84
 85        /// <summary>
 86        /// Creates a frozen snapshot from this node.
 87        /// </summary>
 288        public RouteNode Freeze() => new(this);
 89    }
 90}