/// <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; } }
/// <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)); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); } }
/// <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)); }
/// <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)); } }
/// <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)); }
/// <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 })); }
/// <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);
/// <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]); }
/// <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);
/// <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);
/// <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);