using System.Diagnostics.CodeAnalysis; namespace AvParser.Core.Parsing; /// /// Result of parsing a single record: either a value or a recoverable . /// /// /// A struct rather than a class hierarchy: parsers emit one of these per line, and on a /// million-line input the allocation difference is the whole cost of the parse. /// public readonly record struct ParseOutcome { private ParseOutcome(T? value, ParseError? error) { Value = value; Error = error; } /// The parsed value, or when is false. public T? Value { get; } /// The failure, or when is true. public ParseError? Error { get; } /// when a value was produced. [MemberNotNullWhen(false, nameof(Error))] public bool IsSuccess => Error is null; /// Creates a successful outcome. public static ParseOutcome Success(T value) => new(value, null); /// Creates a failed outcome. public static ParseOutcome Failure(ParseError error) => new(default, error ?? throw new ArgumentNullException(nameof(error))); /// Creates a failed outcome from its parts. public static ParseOutcome Failure(int lineNumber, string message) => Failure(new ParseError(lineNumber, message)); }