public void GetValueFromString(string src, Type expectedType, bool expectedSuccess, object expectedResult) { bool success = CommandlineMethods.GetValueFromString(src, expectedType, out object result); Assert.Equal(expectedSuccess, success); if (success) { Assert.Equal(expectedResult, result); } }
internal override void Interpret() { if (Offset + 1 >= TopInterpreter.Args.Length || IsParameterEqual("help", TopInterpreter.Args[Offset + 1], "?")) { _root.Load(_typeInfoOfConfiguration); HelpGenerators.PrintConfigurationContextHelp(_root, this, true); return; } bool ro = false; IncreaseOffset(); object requiredObject = _referenceToObject; (PropertyInfo prop, object[] indexers, PropertyInfo lastNonIndexer) = ConfigurationHelpers.ResolvePathRecursive(TopInterpreter.Args[Offset], _typeInfoOfConfiguration, ref requiredObject, ref ro); IncreaseOffset(); string Operator = TopInterpreter.Args[Offset]; if (IsParameterEqual("Help", Operator, allowPrefixFree: true)) { var contextAttribute = lastNonIndexer.PropertyType.GetCustomAttribute <CmdConfigurationNamespaceAttribute>(); if (contextAttribute is null) { var valueAttribute = lastNonIndexer.GetCustomAttribute <CmdConfigurationFieldAttribute>(); valueAttribute.Load(new PropertyOrFieldInfo(lastNonIndexer)); HelpGenerators.PrintConfigurationFieldHelp(valueAttribute, this); return; } else { HelpGenerators.PrintConfigurationContextHelp(contextAttribute, this); } } if (IsParameterEqual("Get", Operator, allowPrefixFree: true)) { object currentValue; try { currentValue = indexers is null?prop.GetValue(requiredObject) : prop.GetValue(requiredObject, indexers); } catch (Exception e) { throw new CLIUsageException("An error occurred while obtaining the value requested:", e); } Console.WriteLine(JsonConvert.SerializeObject(currentValue)); return; } if (IsParameterEqual("Set", Operator, allowPrefixFree: true)) { var valueAttribute = prop.GetCustomAttribute <CmdConfigurationFieldAttribute>(); if (ro || !prop.CanWrite) { throw new CLIUsageException("The given property is read only"); } if (IncreaseOffset()) { throw new CLIUsageException("Please supply a value to set the given value to!"); } if (!CommandlineMethods.GetValueFromString(TopInterpreter.Args[Offset], prop.PropertyType, out object newValue)) { throw new CLIUsageException( $"The given string (TopInterpreter.Args[Offset]) couldn't be parsed to {prop.PropertyType}!"); } try { if (indexers is null) { prop.SetValue(requiredObject, newValue); } else { prop.SetValue(requiredObject, newValue, indexers); } } catch (Exception e) { throw new CLIUsageException("An error occurred while writing the value:", e); } if (_referenceToObject is IConfigurationRoot iCfgRoot) { iCfgRoot.Save(Enumerable.Repeat(new PropertyOrFieldInfo(lastNonIndexer), 1)); } return; } if (IsParameterEqual("RemoveAt", Operator, allowPrefixFree: true)) { var valueAttribute = prop.GetCustomAttribute <CmdConfigurationFieldAttribute>(); if (ro || !prop.CanWrite) { throw new CLIUsageException("The given value is not writable"); } if (!typeof(ICollection).IsAssignableFrom(prop.PropertyType)) { throw new CLIUsageException("The object that you try to remove an element from is no collection."); } if (IncreaseOffset()) { throw new CLIUsageException("Please supply a value to set the given value to!"); } if (!CommandlineMethods.GetValueFromString(TopInterpreter.Args[Offset], out int removalIndex)) { throw new CLIUsageException($"The given string couldn't be parsed to {prop.PropertyType}!"); } try { ((IList)(indexers is null ? prop.GetValue(requiredObject) : prop.GetValue(requiredObject, indexers))) .RemoveAt(removalIndex); //Safe due to previous assignability check } catch (Exception e) { throw new CLIUsageException("An error occurred while removing an object:", e); } } throw new CLIUsageException("Could not resolve the operator provided"); //TODO Remove and Add missing //_root.Interpret(printErrors); }
/// <summary> /// Checks if a given parameter matches a specified one /// </summary> /// <param name="expected">The expected parameter</param> /// <param name="given">The given parameter to compare with, null to get next from interpretation task</param> /// <param name="expectedShortForm">The ShortForm of <paramref name="expected"/> null for none</param> /// <param name="allowPrefixFree">Whether it can be used without prefix, defaults to no</param> /// <returns>Whether the given form matched the expected form or its ShortForm</returns> internal bool IsParameterEqual(string expected, string given = null, string expectedShortForm = null, bool allowPrefixFree = false) => CommandlineMethods.IsParameterEqual(expected, given ?? TopInterpreter.Args[Offset], TopInterpreter.Options.IgnoreParameterCase, expectedShortForm, allowPrefixFree);