Example #1
0
        /// <summary>
        /// Tries to parse the provided string, extracting a value of the type
        /// described by this interface.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">The string to parse.</param>
        /// <returns>True on success; false otherwise.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            if (!_commandArgType.TryParse(context, stringToParse, out object selection))
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            var groupOptions = new CommandGroupOptions
            {
                ServiceConfigurer = context.ServiceConfigurer
            };

            var constructorArgTypes     = new[] { typeof(CommandGroupOptions), typeof(object), typeof(object) };
            var commandGroupConstructor = Type.GetTypeInfo().GetConstructor(constructorArgTypes);

            if (commandGroupConstructor == null)
            {
                throw new InternalInvariantBrokenException($"Constructor not found in {Type.FullName}: ({string.Join(", ", constructorArgTypes.Select(ty => ty.FullName))})");
            }

            try
            {
                return(commandGroupConstructor.Invoke(new[] { groupOptions, selection, context.ContainingObject }));
            }
            catch (TargetInvocationException ex)
            {
                throw ex.InnerException;
            }
        }
Example #2
0
        /// <summary>
        /// Not implemented.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            string[] elementStrings;
            if (context.ElementSeparators.Any())
            {
                elementStrings = stringToParse.Split(
                    context.ElementSeparators.ToArray(),
                    StringSplitOptions.None);
            }
            else
            {
                elementStrings = new[] { stringToParse };
            }

            if (context.AllowEmpty)
            {
                if (stringToParse == "" || stringToParse == "[]" || stringToParse == "{}" || stringToParse == "\"\"")
                {
                    return(ToCollection(new object[0]));
                }
            }

            var parsedElements = elementStrings.Select(elementString =>
            {
                if (!_elementArgumentType.TryParse(context, elementString, out object parsedElement))
                {
                    throw new ArgumentOutOfRangeException(nameof(stringToParse));
                }

                return(parsedElement);
            }).ToArray();

            return(ToCollection(parsedElements));
        }
Example #3
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            object parsedObject;

            // Select the appropriate map, based on context.
            var map = context.CaseSensitive ? _valuesByCaseSensitiveName : _valuesByCaseInsensitiveName;

            // First try looking up the string in our name map.
            if (!map.TryGetValue(stringToParse, out IArgumentValue value))
            {
                // We might have more options if it's an enum type, but if it's not--there's
                // nothing else we can do.
                if (!Type.GetTypeInfo().IsEnum)
                {
                    throw new ArgumentOutOfRangeException(nameof(stringToParse));
                }

                // Otherwise, only let through literal integers.
                if (!int.TryParse(stringToParse, NumberStyles.AllowLeadingSign, null, out int parsedInt))
                {
                    throw new ArgumentOutOfRangeException(nameof(stringToParse));
                }

                // Now use base facilities for parsing.
                parsedObject = Enum.Parse(Type, stringToParse, true /* ignore case */);

                // Try looking it up again, this time by value.
                if (!_valuesByValue.TryGetValue(parsedObject, out value))
                {
                    throw new ArgumentOutOfRangeException(nameof(stringToParse));
                }
            }

            return(value.Value);
        }
Example #4
0
        /// <summary>
        /// Tries to parse the provided string, extracting a value of the type
        /// described by this interface.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">The string to parse.</param>
        /// <param name="value">On success, receives the parsed value; null
        /// otherwise.</param>
        /// <returns>True on success; false otherwise.</returns>
        public bool TryParse(ArgumentParseContext context, string stringToParse, out object value)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (stringToParse == null)
            {
                throw new ArgumentNullException(nameof(stringToParse));
            }

            try
            {
                value = Parse(context, stringToParse);
                return(true);
            }
            catch (OverflowException)
            {
            }
            catch (ArgumentException)
            {
            }
            catch (FormatException)
            {
            }

            value = null;
            return(false);
        }
Example #5
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            if (string.IsNullOrEmpty(stringToParse) && !context.AllowEmpty)
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            return(stringToParse);
        }
Example #6
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        /// <exception cref="OverflowException">Thrown when the parsed value would
        /// overflow the integer type represented by this object instance.</exception>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            Debug.Assert(stringToParse != null);

            var   numberStyle = NumberStyles.Integer;
            ulong?multiplier  = null;

            // Inspect the number string's prefix, likely indicating the number's
            // style.
            if (stringToParse.StartsWith("0x", StringComparison.Ordinal))
            {
                stringToParse = stringToParse.Remove(0, 2);
                numberStyle   = NumberStyles.HexNumber;
            }
            else if (stringToParse.StartsWith("0n", StringComparison.Ordinal))
            {
                stringToParse = stringToParse.Remove(0, 2);
                numberStyle   = NumberStyles.Integer;
            }

            // Inspect the number string's suffix, that is if we've been allowed
            // to do so.
            if (context.NumberOptions.HasFlag(NumberOptions.AllowBinaryMetricUnitSuffix))
            {
                stringToParse = RemoveUnitSuffix(stringToParse, true, out multiplier);
            }
            else if (context.NumberOptions.HasFlag(NumberOptions.AllowMetricUnitSuffix))
            {
                stringToParse = RemoveUnitSuffix(stringToParse, false, out multiplier);
            }

            // If the number is not being scaled, then directly parse and return
            // it.
            if (!multiplier.HasValue)
            {
                return(_parseHandler(stringToParse, numberStyle));
            }
            else
            {
                var decimalValue = decimal.Parse(
                    stringToParse,
                    numberStyle | NumberStyles.AllowDecimalPoint,
                    CultureInfo.CurrentCulture);

                var scaledDecimalValue = decimalValue * multiplier.Value;
                var scaledLongValue    = Convert.ToInt64(scaledDecimalValue);

                if (scaledLongValue != scaledDecimalValue)
                {
                    throw new OverflowException();
                }

                var scaledStringValue = scaledLongValue.ToString(CultureInfo.InvariantCulture);
                return(_parseHandler(scaledStringValue, NumberStyles.Integer));
            }
        }
Example #7
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            var pieces = stringToParse.Split('|').ToList();

            if ((pieces.Count == 0) || ((pieces.Count == 1) && (pieces[0].Length == 0)))
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            var underlyingResult =
                pieces.Select(piece => Convert.ChangeType(base.Parse(context, piece), _underlyingType))
                .Aggregate(_underlyingIntegerType.Or);

            return(Enum.ToObject(Type, underlyingResult));
        }
Example #8
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            if (string.IsNullOrEmpty(stringToParse))
            {
                return(true);
            }

            switch (stringToParse)
            {
            case "+":
                return(true);

            case "-":
                return(false);

            default:
                return(bool.Parse(stringToParse));
            }
        }
Example #9
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            var tokens = stringToParse.Split(ItemSeparatorChar);

            if (tokens.Length != _typeParameters.Length)
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse), Strings.TooFewElementsInTupleString);
            }

            var parsedObjects = new object[_typeParameters.Length];

            for (var i = 0; i < tokens.Length; ++i)
            {
                if (!_argTypeParameters[i].TryParse(context, tokens[i], out parsedObjects[i]))
                {
                    throw new ArgumentOutOfRangeException(nameof(stringToParse));
                }
            }

            return(_creatorMethod.Invoke(parsedObjects));
        }
Example #10
0
        /// <summary>
        /// Parses the provided string.  Throws an exception if the string
        /// cannot be parsed.
        /// </summary>
        /// <param name="context">Context for parsing.</param>
        /// <param name="stringToParse">String to parse.</param>
        /// <returns>The parsed object.</returns>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when
        /// <paramref name="stringToParse" /> is not a well-formed encoding of a
        /// key/value pair</exception>
        protected override object Parse(ArgumentParseContext context, string stringToParse)
        {
            var separatorIndex = stringToParse.IndexOf(KeyValueSeparatorChar);

            if (separatorIndex < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            var keyString   = stringToParse.Substring(0, separatorIndex);
            var valueString = stringToParse.Substring(separatorIndex + 1);

            if (!_keyType.TryParse(context, keyString, out object key))
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            if (!_valueType.TryParse(context, valueString, out object value))
            {
                throw new ArgumentOutOfRangeException(nameof(stringToParse));
            }

            return(_constructor.Invoke(new[] { key, value }));
        }
Example #11
0
 /// <summary>
 /// Parses the provided string.  Throws an exception if the string
 /// cannot be parsed.
 /// </summary>
 /// <param name="context">Context for parsing.</param>
 /// <param name="stringToParse">String to parse.</param>
 /// <returns>The parsed object.</returns>
 protected override object Parse(ArgumentParseContext context, string stringToParse) =>
 _parseHandler(stringToParse);
Example #12
0
        /// <summary>
        /// Given a parser context, returns the preferred element separator. Returns null
        /// if no such separator exists.
        /// </summary>
        /// <param name="context">Parser context.</param>
        /// <returns>Preferred element separator, if one exists; null otherwise.</returns>
        private static string GetPreferredElementSeparatorOrDefault(ArgumentParseContext context)
        {
            var seps = context.ElementSeparators;

            return((seps.Count == 0) ? null : seps[0]);
        }
Example #13
0
 /// <summary>
 /// Tries to parse the provided string, extracting a value of the type
 /// described by this interface.
 /// </summary>
 /// <param name="context">Context for parsing.</param>
 /// <param name="stringToParse">The string to parse.</param>
 /// <param name="value">On success, receives the parsed value; null
 /// otherwise.</param>
 /// <returns>True on success; false otherwise.</returns>
 public abstract bool TryParse(ArgumentParseContext context, string stringToParse, out object value);
Example #14
0
 /// <summary>
 /// Tries to parse the provided string, extracting a value of the type
 /// described by this interface.
 /// </summary>
 /// <param name="context">Context for parsing.</param>
 /// <param name="stringToParse">The string to parse.</param>
 /// <param name="value">On success, receives the parsed value; null
 /// otherwise.</param>
 /// <returns>True on success; false otherwise.</returns>
 public virtual bool TryParse(ArgumentParseContext context, string stringToParse, out object value) =>
 (Parser ?? InnerType).TryParse(context, stringToParse, out value);
Example #15
0
 /// <summary>
 /// Parses the provided string.  Throws an exception if the string
 /// cannot be parsed.
 /// </summary>
 /// <param name="context">Context for parsing.</param>
 /// <param name="stringToParse">String to parse.</param>
 /// <returns>The parsed object.</returns>
 protected abstract object Parse(ArgumentParseContext context, string stringToParse);