public void InvalidReader() { var context = new ArgumentParseContext(); Action setNull = () => context.FileSystemReader = null; setNull.ShouldThrow<ArgumentNullException>(); }
/// <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 }; } 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> /// <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), _commandTypeType, 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; } }
public bool TryParse(ArgumentParseContext context, string stringToParse, out object value) { 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)); } }
public bool TryParse(ArgumentParseContext context, string stringToParse, out object value) { if (!stringToParse.StartsWith("|") || !stringToParse.EndsWith("|") || stringToParse.Length < 2) { value = null; return false; } value = stringToParse.Substring(1, stringToParse.Length - 2); return true; }
/// <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) { 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> /// 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) { var elementStrings = stringToParse.Split(ElementSeparatorChar); 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) { if (string.IsNullOrEmpty(stringToParse)) { return(true); } switch (stringToParse) { case "+": return(true); case "-": return(false); default: return(bool.Parse(stringToParse)); } }
/// <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) { 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) { 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)); }
protected override object Parse(ArgumentParseContext context, string stringToParse) { if (!_commandArgType.TryParse(context, stringToParse, out object selection)) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } var commandGroupConstructor = Type.GetTypeInfo().GetConstructor(new[] { _commandTypeType }); if (commandGroupConstructor == null) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } var group = commandGroupConstructor.Invoke(new[] { selection }); if (group == null) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } return(group); }
/// <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 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 })); }
public void ParsingDecimalUnits() { var context = new ArgumentParseContext { NumberOptions = NumberOptions.AllowMetricUnitSuffix }; object value; ArgumentType.Int.TryParse(context, "1.1234k", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "1.5k", out value).Should().BeTrue(); value.Should().Be(1500); ArgumentType.Int.TryParse(context, "1.333k", out value).Should().BeTrue(); value.Should().Be(1333); ArgumentType.Int.TryParse(context, "-1.5k", out value).Should().BeTrue(); value.Should().Be(-1500); ArgumentType.Int.TryParse(context, "1.5k", out value).Should().BeTrue(); value.Should().Be(1500); ArgumentType.UInt.TryParse(context, "-1.5k", out value).Should().BeFalse(); }
public void ParsingUnitsWithOverflow() { var context = new ArgumentParseContext { NumberOptions = NumberOptions.AllowBinaryMetricUnitSuffix }; object value; ArgumentType.Int.TryParse(context, "10GB", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "10TB", out value).Should().BeFalse(); }
/// <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 separatorIndex = stringToParse.IndexOf(KeyValueSeparatorChar); if (separatorIndex < 0) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } var keyString = stringToParse.Substring(0, separatorIndex); var valueString = stringToParse.Substring(separatorIndex + 1); object key; if (!_keyType.TryParse(context, keyString, out key)) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } object value; if (!_valueType.TryParse(context, valueString, out 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 abstract object Parse(ArgumentParseContext context, string stringToParse);
public void ParsingBinaryUnits() { var defaultContext = ArgumentParseContext.Default; var context = new ArgumentParseContext { NumberOptions = NumberOptions.AllowBinaryMetricUnitSuffix }; object value; ArgumentType.Int.TryParse(defaultContext, "3k", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3b", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3ib", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3B", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "k", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "M", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3", out value).Should().BeTrue(); value.Should().Be(3); foreach (var s in new[] { "3k", "3KB", "3KiB", "3kB" }) { ArgumentType.Int.TryParse(context, s, out value).Should().BeTrue(); value.Should().Be(3 * 1024); } foreach (var s in new[] { "3M", "3MB", "3MiB" }) { ArgumentType.Int.TryParse(context, s, out value).Should().BeTrue(); value.Should().Be(3 * 1024 * 1024); } ArgumentType.Int.TryParse(context, "1G", out value).Should().BeTrue(); value.Should().Be(1024 * 1024 * 1024); ArgumentType.Long.TryParse(context, "2T", out value).Should().BeTrue(); value.Should().Be(2L * 1024 * 1024 * 1024 * 1024); ArgumentType.Long.TryParse(context, "2P", out value).Should().BeTrue(); value.Should().Be(2L * 1024 * 1024 * 1024 * 1024 * 1024); ArgumentType.Long.TryParse(context, "2E", out value).Should().BeTrue(); value.Should().Be(2L * 1024 * 1024 * 1024 * 1024 * 1024 * 1024); ArgumentType.Long.TryParse(context, "2Z", out value).Should().BeFalse(); ArgumentType.Long.TryParse(context, "2Y", out value).Should().BeFalse(); }
/// <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> /// 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> /// 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) { var elementStrings = stringToParse.Split(ElementSeparatorChar); var parsedElements = elementStrings.Select(elementString => { object parsedElement; if (!_elementArgumentType.TryParse(context, elementString, out parsedElement)) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } return parsedElement; }).ToArray(); return ToCollection(parsedElements); }
/// <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> /// 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) { FieldInfo field; // First try looking up the string in our name map. if (_valueNameMap.TryGetValue(stringToParse, out field)) { stringToParse = field.Name; } // Now use base facilities for parsing. var parsedObject = Enum.Parse(Type, stringToParse, true /* ignore case */); // Try to look find any <see cref="ArgumentValueAttribute" /> // associated with this value. var name = Enum.GetName(Type, parsedObject); if (IsValueDisallowed(name)) { throw new ArgumentOutOfRangeException(nameof(stringToParse)); } return parsedObject; }
/// <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]; // ReSharper disable once LoopCanBeConvertedToQuery 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); }
public void ParsingNonBinaryUnits() { var defaultContext = ArgumentParseContext.Default; var context = new ArgumentParseContext { NumberOptions = NumberOptions.AllowMetricUnitSuffix }; object value; ArgumentType.Int.TryParse(defaultContext, "3k", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3kB", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3MB", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3T", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3DA", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3H", out value).Should().BeFalse(); ArgumentType.Int.TryParse(context, "3", out value).Should().BeTrue(); value.Should().Be(3); ArgumentType.Int.TryParse(context, "3da", out value).Should().BeTrue(); value.Should().Be(30); ArgumentType.Int.TryParse(context, "3h", out value).Should().BeTrue(); value.Should().Be(300); ArgumentType.Int.TryParse(context, "3k", out value).Should().BeTrue(); value.Should().Be(3000); ArgumentType.Int.TryParse(context, "3M", out value).Should().BeTrue(); value.Should().Be(3000000); }