public static void TryParseError(string text, string expectedError)
        {
            var success = CompositeFormatParser.TryParse(text, out QuantityFormat <LengthUnit> actual);

            Assert.AreEqual(false, success);
            Assert.AreEqual(expectedError, actual.ErrorText);
        }
        public static void TryParsePressure(string format, string expectedFormat, string expectedSymbol)
        {
            var success = CompositeFormatParser.TryParse(format, out QuantityFormat <PressureUnit> actual);

            Assert.AreEqual(true, success);
            Assert.AreEqual(expectedFormat, actual.CompositeFormat);
            Assert.AreEqual(expectedSymbol, actual.Unit.Symbol);
        }
        public static void TryParseSuccess(string format, string expectedFormat, string expectedFormatted)
        {
            var success = CompositeFormatParser.TryParse(format, out QuantityFormat <LengthUnit> actual);

            Assert.AreEqual(true, success);
            Assert.AreEqual(expectedFormat, actual.CompositeFormat);

            var length          = Length.FromMetres(1.2);
            var actualFormatted = length.ToString(format, CultureInfo.InvariantCulture);

            Assert.AreEqual(expectedFormatted, actualFormatted);
        }
        internal static bool TryParse(string?format, [MaybeNullWhen(false)] out QuantityFormat <TUnit> result)
        {
            if (string.IsNullOrWhiteSpace(format))
            {
                result = QuantityFormat <TUnit> .CreateUnknown("{nameof(format) is null}", Unit <TUnit> .Default);

                return(false);
            }

            if (Cache.TryGetValue(format, out result))
            {
                return(true);
            }

            var pos = 0;

            _ = WhiteSpaceReader.TryRead(format, ref pos);
            var end = format.Length;

            if (TryReadPrefix(format, ref pos))
            {
                end = format.LastIndexOf('}');
                if (end < 0)
                {
                    result = QuantityFormat <TUnit> .CreateUnknown(format, Unit <TUnit> .Default);

                    return(false);
                }

                if (!WhiteSpaceReader.IsRestWhiteSpace(format, end + 1))
                {
                    result = QuantityFormat <TUnit> .CreateUnknown(format, Unit <TUnit> .Default);

                    return(false);
                }
            }

            var trimmedFormat = pos != end
                ? format.Substring(pos, end - pos)
                : format;

            var success = CompositeFormatParser.TryParse(trimmedFormat, out result);

            if (success)
            {
                Cache.Add(format, result);
            }

            return(success);
        }