File: Parsing\OptionResult.cs
Web Access
Project: src\src\command-line-api\src\System.CommandLine\System.CommandLine.csproj (System.CommandLine)
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.CommandLine.Binding;
using System.Linq;

namespace System.CommandLine.Parsing
{
    /// <summary>
    /// Represents a result produced when parsing an <see cref="Option" />.
    /// </summary>
    public sealed class OptionResult : SymbolResult
    {
        internal OptionResult(
            Option option,
            SymbolResultTree symbolResultTree,
            Token? token = null,
            CommandResult? parent = null) :
            base(symbolResultTree, parent)
        {
            Option = option ?? throw new ArgumentNullException(nameof(option));
            IdentifierToken = token;
        }

        /// <summary>
        /// Gets the option to which the result applies.
        /// </summary>
        public Option Option { get; }

        /// <summary>
        /// Gets a value that indicates whether the result was created implicitly and not due to the option being specified on the command line.
        /// </summary>
        /// <remarks>Implicit results commonly result from options having a default value.</remarks>
        public bool Implicit => IdentifierToken is null || IdentifierToken.Implicit;

        /// <summary>
        /// Gets the token that was parsed to specify the option.
        /// </summary>
        /// <remarks>An identifier token is a token that matches either the option's name or one of its aliases.</remarks>
        public Token? IdentifierToken { get; }

        /// <summary>
        /// Gets the number of occurrences of an identifier token matching the option.
        /// </summary>
        public int IdentifierTokenCount { get; internal set; }

        /// <inheritdoc/>
        public override string ToString() => $"{nameof(OptionResult)}: {IdentifierToken?.Value ?? Option.Name} {string.Join(" ", Tokens.Select(t => t.Value))}";

        /// <summary>
        /// Gets the parsed value or the default value for <see cref="Option"/>.
        /// </summary>
        /// <returns>The parsed value or the default value for <see cref="Option"/></returns>
        public T GetValueOrDefault<T>() =>
            GetResult(Option.Argument)!.GetValueOrDefault<T>();

        internal bool IsArgumentLimitReached
            => Option.Argument.Arity.MaximumNumberOfValues == (Implicit ? Tokens.Count - 1 : Tokens.Count);

        internal ArgumentConversionResult ArgumentConversionResult
            => GetResult(Option.Argument)!.GetArgumentConversionResult();

        internal override bool UseDefaultValueFor(ArgumentResult argumentResult)
        {
            if (Implicit)
            {
                return true;
            }

            return Tokens.Count is 0 &&
                   Option.Arity is { MinimumNumberOfValues: 0, MaximumNumberOfValues: > 0 } &&
                   !argumentResult.Argument.IsBoolean();
        }
    }
}