/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } var enumerable = value as IEnumerable; if (enumerable == null) { return(false); } if (value.GetType().IsDictionary()) { return(false); } var elements = enumerable.Cast <object>(); if (_config.ItemLimit > 0) { elements = elements.Take(_config.ItemLimit); } result = new SequenceToken(elements.Select(converter.Convert)); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } var bytes = value as byte[]; if (bytes == null) { return(false); } //Enforce limit on size of array if (_config.ByteArrayLimit > 0 && bytes.Length > _config.ByteArrayLimit) { string hexValue = string.Concat(bytes.Take(16).Select(b => b.ToString("X2"))); string description = $"0x: {hexValue}... ({bytes.Length} bytes)"; result = new ScalarToken(description); return(true); } result = new ScalarToken(bytes.ToArray()); return(true); }
/// <summary> /// Create a <see cref="PropertyToken"/> with the provided name and value. /// </summary> /// <param name="name">The name of the property.</param> /// <param name="value">The value of the property.</param> internal PropertyToken(string name, IPropertyToken value) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } Name = name; Value = value ?? throw new ArgumentNullException(nameof(value)); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } var enumerable = value as IEnumerable; if (enumerable == null) { return(false); } // Only dictionaries with 'scalar' keys are permitted, as // more complex keys may not serialize to unique values for // representation in targets. This check strengthens the expectation // that resulting dictionary is representable in JSON as well // as richer formats (e.g. XML, .NET type-aware...). // Only actual dictionaries are supported, as arbitrary types // can implement multiple IDictionary interfaces and thus introduce // multiple different interpretations. var type = value.GetType(); if (!type.IsDictionary()) { return(false); } var typeInfo = typeof(KeyValuePair <,>).MakeGenericType(type.GenericTypeArguments).GetTypeInfo(); var keyProperty = typeInfo.GetDeclaredProperty("Key"); var valueProperty = typeInfo.GetDeclaredProperty("Value"); var items = enumerable.Cast <object>(); if (_config.ItemLimit > 0) { items = items.Take(_config.ItemLimit); } var elements = items .Select(kvp => new KeyValuePair <ScalarToken, IPropertyToken>( (ScalarToken)converter.Convert(keyProperty.GetValue(kvp)), converter.Convert(valueProperty.GetValue(kvp)) ) ) .Where(kvp => kvp.Key.Value != null); result = new DictionaryToken(elements); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } var del = value as Delegate; if (del == null) { return(false); } result = new ScalarToken(del.GetMethodInfo().ToString()); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } if (value == null) { return(false); } var type = value.GetType(); string typeName = type.IsCompilerGenerated() ? null : type.Name; result = new StructureToken(GetProperties(value, converter), typeName); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } // These types and their subclasses are property-laden and deep // Most of targets will convert them to strings if (!(value is Type) && !(value is MemberInfo)) { return(false); } result = new ScalarToken(value.ToString()); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } if (value == null) { return(false); } if (!value.GetType().GetTypeInfo().IsEnum) { return(false); } result = new ScalarToken(value); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } string text = value as string; if (text == null) { return(false); } if (_config.StringLimit > 0 && text.Length > _config.StringLimit) { text = text.Substring(0, _config.StringLimit) + "…"; } result = new ScalarToken(text); return(true); }
/// <summary> /// If supported, convert the provided value into a <see cref="IPropertyToken"/>. /// </summary> /// <param name="converter">Converter for conversion of additional values.</param> /// <param name="value">The value to convert.</param> /// <param name="result">Value converted to <see cref="IPropertyToken"/> if conversion was successful.</param> /// <returns><c>true</c> if the value could be converted under this policy; <c>false</c> otherwise.</returns> public bool TryConvert(IPropertyConverter converter, object value, out IPropertyToken result) { result = null; if (converter == null) { throw new ArgumentNullException(nameof(converter)); } if (value == null) { result = new ScalarToken(null); return(true); } #if NET45 || NET46 if (value is DBNull) { result = new ScalarToken(null); return(true); } #endif return(false); }