зеркало из https://github.com/stride3d/SharpYaml.git
Make remaining tests pass using Deserializer.
Use TypeConvertert from SixPack instead of ObjectConverter.
This commit is contained in:
Родитель
3e873fb624
Коммит
f4182bd8cd
|
@ -76,8 +76,8 @@ namespace YamlDotNet.Configuration
|
||||||
|
|
||||||
private void LoadSections(TextReader yaml)
|
private void LoadSections(TextReader yaml)
|
||||||
{
|
{
|
||||||
YamlSerializer serializer = new YamlSerializer(typeof(Dictionary<string, object>));
|
var deserializer = new Deserializer();
|
||||||
sections = (IDictionary<string, object>)serializer.Deserialize(yaml);
|
sections = (IDictionary<string, object>)deserializer.Deserialize(yaml, typeof(Dictionary<string, object>));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IConfigurationProvider Members
|
#region IConfigurationProvider Members
|
||||||
|
|
|
@ -115,16 +115,14 @@ namespace YamlDotNet.Configuration
|
||||||
yaml = GetYamlContent(section);
|
yaml = GetYamlContent(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
YamlSerializer serializer;
|
var sectionType = typeof(object);
|
||||||
if (section.Attributes["type"] != null)
|
if (section.Attributes["type"] != null)
|
||||||
{
|
{
|
||||||
serializer = new YamlSerializer(Type.GetType(section.Attributes["type"].Value, true));
|
sectionType = Type.GetType(section.Attributes["type"].Value, true);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
var deserializer = new Deserializer();
|
||||||
serializer = new YamlSerializer();
|
return deserializer.Deserialize(yaml, sectionType);
|
||||||
}
|
|
||||||
return serializer.Deserialize(yaml);
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
private readonly List<IYamlTypeConverter> converters;
|
private readonly List<IYamlTypeConverter> converters;
|
||||||
private TypeDescriptorProxy typeDescriptor = new TypeDescriptorProxy();
|
private TypeDescriptorProxy typeDescriptor = new TypeDescriptorProxy();
|
||||||
|
|
||||||
public IList<INodeDeserializer> Deserializers { get; private set; }
|
public IList<INodeDeserializer> NodeDeserializers { get; private set; }
|
||||||
public IList<INodeTypeResolver> TypeResolvers { get; private set; }
|
public IList<INodeTypeResolver> TypeResolvers { get; private set; }
|
||||||
|
|
||||||
private class TypeDescriptorProxy : ITypeDescriptor
|
private class TypeDescriptorProxy : ITypeDescriptor
|
||||||
|
@ -78,17 +78,17 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
);
|
);
|
||||||
|
|
||||||
converters = new List<IYamlTypeConverter>();
|
converters = new List<IYamlTypeConverter>();
|
||||||
Deserializers = new List<INodeDeserializer>();
|
NodeDeserializers = new List<INodeDeserializer>();
|
||||||
Deserializers.Add(new TypeConverterNodeDeserializer(converters));
|
NodeDeserializers.Add(new TypeConverterNodeDeserializer(converters));
|
||||||
Deserializers.Add(new NullNodeDeserializer());
|
NodeDeserializers.Add(new NullNodeDeserializer());
|
||||||
Deserializers.Add(new ScalarNodeDeserializer());
|
NodeDeserializers.Add(new ScalarNodeDeserializer());
|
||||||
Deserializers.Add(new ArrayNodeDeserializer());
|
NodeDeserializers.Add(new ArrayNodeDeserializer());
|
||||||
Deserializers.Add(new GenericDictionaryNodeDeserializer(objectFactory));
|
NodeDeserializers.Add(new GenericDictionaryNodeDeserializer(objectFactory));
|
||||||
Deserializers.Add(new NonGenericDictionaryNodeDeserializer(objectFactory));
|
NodeDeserializers.Add(new NonGenericDictionaryNodeDeserializer(objectFactory));
|
||||||
Deserializers.Add(new GenericCollectionNodeDeserializer(objectFactory));
|
NodeDeserializers.Add(new GenericCollectionNodeDeserializer(objectFactory));
|
||||||
Deserializers.Add(new NonGenericListNodeDeserializer(objectFactory));
|
NodeDeserializers.Add(new NonGenericListNodeDeserializer(objectFactory));
|
||||||
Deserializers.Add(new EnumerableNodeDeserializer());
|
NodeDeserializers.Add(new EnumerableNodeDeserializer());
|
||||||
Deserializers.Add(new ObjectNodeDeserializer(objectFactory, typeDescriptor));
|
NodeDeserializers.Add(new ObjectNodeDeserializer(objectFactory, typeDescriptor));
|
||||||
|
|
||||||
tagMappings = new Dictionary<string, Type>(predefinedTagMappings);
|
tagMappings = new Dictionary<string, Type>(predefinedTagMappings);
|
||||||
TypeResolvers = new List<INodeTypeResolver>();
|
TypeResolvers = new List<INodeTypeResolver>();
|
||||||
|
@ -99,7 +99,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
base.SetValueDeserializer(
|
base.SetValueDeserializer(
|
||||||
new AliasValueDeserializer(
|
new AliasValueDeserializer(
|
||||||
new NodeValueDeserializer(
|
new NodeValueDeserializer(
|
||||||
Deserializers,
|
NodeDeserializers,
|
||||||
TypeResolvers
|
TypeResolvers
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -56,7 +56,8 @@ namespace YamlDotNet.RepresentationModel.Serialization.NodeDeserializers
|
||||||
|
|
||||||
var property = _typeDescriptor.GetProperty(expectedType, propertyName.Value).Property;
|
var property = _typeDescriptor.GetProperty(expectedType, propertyName.Value).Property;
|
||||||
var propertyValue = nestedObjectDeserializer(reader, property.PropertyType);
|
var propertyValue = nestedObjectDeserializer(reader, property.PropertyType);
|
||||||
property.SetValue(value, propertyValue, null);
|
var convertedValue = TypeConverter.ChangeType(propertyValue, property.PropertyType);
|
||||||
|
property.SetValue(value, convertedValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
reader.Expect<MappingEnd>();
|
reader.Expect<MappingEnd>();
|
||||||
|
|
|
@ -116,15 +116,7 @@ namespace YamlDotNet.RepresentationModel.Serialization.NodeDeserializers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TypeConverter converter = TypeDescriptor.GetConverter(expectedType);
|
value = TypeConverter.ChangeType(scalar.Value, expectedType);
|
||||||
if (converter != null && converter.CanConvertFrom(typeof(string)))
|
|
||||||
{
|
|
||||||
value = converter.ConvertFromInvariantString(scalar.Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = Convert.ChangeType(scalar.Value, expectedType, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
// This file is part of YamlDotNet - A .NET library for YAML.
|
|
||||||
// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry
|
|
||||||
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
|
||||||
// the Software without restriction, including without limitation the rights to
|
|
||||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
// of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
// so, subject to the following conditions:
|
|
||||||
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Globalization;
|
|
||||||
|
|
||||||
namespace YamlDotNet.RepresentationModel.Serialization
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Performs type conversions.
|
|
||||||
/// </summary>
|
|
||||||
public static class ObjectConverter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to convert the specified value to another type using various approaches.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The value.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// The conversion is first attempted by ditect casting.
|
|
||||||
/// If it fails, the it attempts to use the <see cref="IConvertible"/> interface.
|
|
||||||
/// If it still fails, it tries to use the <see cref="TypeConverter"/> of the value's type, and then the <see cref="TypeConverter"/> of the <typeparamref name="TTo"/> type.
|
|
||||||
/// </remarks>
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null.</exception>
|
|
||||||
/// <exception cref="InvalidCastException">The value cannot be converted to the specified type.</exception>
|
|
||||||
public static TTo Convert<TFrom, TTo>(TFrom value)
|
|
||||||
{
|
|
||||||
return (TTo)Convert(value, typeof(TTo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to convert the specified value to another type using various approaches.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value">The value.</param>
|
|
||||||
/// <param name="to">To.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
/// <remarks>
|
|
||||||
/// The conversion is first attempted by ditect casting.
|
|
||||||
/// If it fails, it tries to use the <see cref="TypeConverter" /> of the value's type, and then the <see cref="TypeConverter" /> of the <paramref name="to" /> type.
|
|
||||||
/// If it still fails, the it attempts to use the <see cref="IConvertible"/> interface.
|
|
||||||
/// </remarks>
|
|
||||||
/// <exception cref="ArgumentNullException">Either <paramref name="value"/> or <paramref name="to"/> are null.</exception>
|
|
||||||
/// <exception cref="InvalidCastException">The value cannot be converted to the specified type.</exception>
|
|
||||||
public static object Convert(object value, Type to)
|
|
||||||
{
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("value");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (to == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("to");
|
|
||||||
}
|
|
||||||
|
|
||||||
Type from = value.GetType();
|
|
||||||
if (from == to || to.IsAssignableFrom(from))
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeConverter resultTypeConverter = TypeDescriptor.GetConverter(from);
|
|
||||||
if (resultTypeConverter != null && resultTypeConverter.CanConvertTo(to))
|
|
||||||
{
|
|
||||||
return resultTypeConverter.ConvertTo(value, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeConverter expectedTypeConverter = TypeDescriptor.GetConverter(to);
|
|
||||||
if (expectedTypeConverter != null && expectedTypeConverter.CanConvertFrom(from))
|
|
||||||
{
|
|
||||||
return expectedTypeConverter.ConvertFrom(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof(IConvertible).IsAssignableFrom(from))
|
|
||||||
{
|
|
||||||
return System.Convert.ChangeType(value, to, CultureInfo.InvariantCulture);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new InvalidCastException(string.Format(CultureInfo.InvariantCulture, "Cannot convert from type '{0}' to type '{1}'.", from.FullName, to.FullName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +1,24 @@
|
||||||
|
// This file is part of YamlDotNet - A .NET library for YAML.
|
||||||
|
// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry
|
||||||
|
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
// of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
// so, subject to the following conditions:
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
// This file is part of YamlDotNet - A .NET library for YAML.
|
||||||
|
// Copyright (c) 2011, 2012, 2013 Antoine Aubry
|
||||||
|
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||||
|
// of the Software, and to permit persons to whom the Software is furnished to do
|
||||||
|
// so, subject to the following conditions:
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
// SOFTWARE.
|
||||||
|
|
||||||
|
// Remarks: This file is imported from the SixPack library. This is ok because
|
||||||
|
// the copyright holder has agreed to redistribute this file under the license
|
||||||
|
// used in YamlDotNet.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Performs type conversions using every standard provided by the .NET library.
|
||||||
|
/// </summary>
|
||||||
|
public static class TypeConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers a <see cref="System.ComponentModel.TypeConverter"/> dynamically.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TConvertible">The type to which the coverter should be associated.</typeparam>
|
||||||
|
/// <typeparam name="TConverter">The type of the converter.</typeparam>
|
||||||
|
public static void RegisterTypeConverter<TConvertible, TConverter>()
|
||||||
|
where TConverter : System.ComponentModel.TypeConverter
|
||||||
|
{
|
||||||
|
var alreadyRegistered = TypeDescriptor.GetAttributes(typeof(TConvertible))
|
||||||
|
.OfType<TypeConverterAttribute>()
|
||||||
|
.Any(a => a.ConverterTypeName == typeof(TConverter).AssemblyQualifiedName);
|
||||||
|
|
||||||
|
if (!alreadyRegistered)
|
||||||
|
{
|
||||||
|
TypeDescriptor.AddAttributes(typeof(TConvertible), new TypeConverterAttribute(typeof(TConverter)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type to which the value is to be converted.</typeparam>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T ChangeType<T>(object value)
|
||||||
|
{
|
||||||
|
return (T)ChangeType(value, typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type to which the value is to be converted.</typeparam>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <param name="provider">The provider.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T ChangeType<T>(object value, IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return (T)ChangeType(value, typeof(T), provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type to which the value is to be converted.</typeparam>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <param name="culture">The culture.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T ChangeType<T>(object value, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return (T)ChangeType(value, typeof(T), culture);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value using the invariant culture.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <param name="destinationType">The type to which the value is to be converted.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object ChangeType(object value, Type destinationType)
|
||||||
|
{
|
||||||
|
return ChangeType(value, destinationType, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <param name="destinationType">The type to which the value is to be converted.</param>
|
||||||
|
/// <param name="provider">The format provider.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object ChangeType(object value, Type destinationType, IFormatProvider provider)
|
||||||
|
{
|
||||||
|
return ChangeType(value, destinationType, new CultureInfoAdapter(CultureInfo.CurrentCulture, provider));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to convert.</param>
|
||||||
|
/// <param name="destinationType">The type to which the value is to be converted.</param>
|
||||||
|
/// <param name="culture">The culture.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object ChangeType(object value, Type destinationType, CultureInfo culture)
|
||||||
|
{
|
||||||
|
// Handle null and DBNull
|
||||||
|
if (value == null || value is DBNull)
|
||||||
|
{
|
||||||
|
return destinationType.IsValueType ? Activator.CreateInstance(destinationType) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceType = value.GetType();
|
||||||
|
|
||||||
|
// If the source type is compatible with the destination type, no conversion is needed
|
||||||
|
if (destinationType.IsAssignableFrom(sourceType))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nullable types get a special treatment
|
||||||
|
if (destinationType.IsGenericType)
|
||||||
|
{
|
||||||
|
var genericTypeDefinition = destinationType.GetGenericTypeDefinition();
|
||||||
|
if (genericTypeDefinition == typeof(Nullable<>))
|
||||||
|
{
|
||||||
|
var innerType = destinationType.GetGenericArguments()[0];
|
||||||
|
var convertedValue = ChangeType(value, innerType, culture);
|
||||||
|
return Activator.CreateInstance(destinationType, convertedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enums also require special handling
|
||||||
|
if (destinationType.IsEnum)
|
||||||
|
{
|
||||||
|
var valueText = value as string;
|
||||||
|
return valueText != null ? Enum.Parse(destinationType, valueText, true) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case for booleans to support parsing "1" and "0". This is
|
||||||
|
// necessary for compatibility with XML Schema.
|
||||||
|
if (destinationType == typeof(bool))
|
||||||
|
{
|
||||||
|
if ("0".Equals(value))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ("1".Equals(value))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try with the source type's converter
|
||||||
|
var sourceConverter = TypeDescriptor.GetConverter(value);
|
||||||
|
if (sourceConverter != null && sourceConverter.CanConvertTo(destinationType))
|
||||||
|
{
|
||||||
|
return sourceConverter.ConvertTo(null, culture, value, destinationType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try with the destination type's converter
|
||||||
|
var destinationConverter = TypeDescriptor.GetConverter(destinationType);
|
||||||
|
if (destinationConverter != null && destinationConverter.CanConvertFrom(sourceType))
|
||||||
|
{
|
||||||
|
return destinationConverter.ConvertFrom(null, culture, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a casting operator in the source or destination type
|
||||||
|
foreach (var type in new[] { sourceType, destinationType })
|
||||||
|
{
|
||||||
|
foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
|
||||||
|
{
|
||||||
|
var isCastingOperator =
|
||||||
|
method.IsSpecialName &&
|
||||||
|
(method.Name == "op_Implicit" || method.Name == "op_Explicit") &&
|
||||||
|
destinationType.IsAssignableFrom(method.ReturnParameter.ParameterType);
|
||||||
|
|
||||||
|
if (isCastingOperator)
|
||||||
|
{
|
||||||
|
var parameters = method.GetParameters();
|
||||||
|
|
||||||
|
var isCompatible =
|
||||||
|
parameters.Length == 1 &&
|
||||||
|
parameters[0].ParameterType.IsAssignableFrom(sourceType);
|
||||||
|
|
||||||
|
if (isCompatible)
|
||||||
|
{
|
||||||
|
return method.Invoke(null, new[] { value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If source type is string, try to find a Parse or TryParse method
|
||||||
|
if (sourceType == typeof(string))
|
||||||
|
{
|
||||||
|
// Try with - public static T Parse(string, IFormatProvider)
|
||||||
|
var parseMethod = destinationType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string), typeof(IFormatProvider) }, null);
|
||||||
|
if (parseMethod != null)
|
||||||
|
{
|
||||||
|
return parseMethod.Invoke(null, new object[] { value, culture });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try with - public static T Parse(string)
|
||||||
|
parseMethod = destinationType.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(string) }, null);
|
||||||
|
if (parseMethod != null)
|
||||||
|
{
|
||||||
|
return parseMethod.Invoke(null, new object[] { value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle TimeSpan
|
||||||
|
if (destinationType == typeof(TimeSpan))
|
||||||
|
{
|
||||||
|
return TimeSpan.Parse((string)ChangeType(value, typeof(string), CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to the Convert class
|
||||||
|
return Convert.ChangeType(value, destinationType, CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CultureInfoAdapter : CultureInfo
|
||||||
|
{
|
||||||
|
private readonly IFormatProvider _provider;
|
||||||
|
|
||||||
|
public CultureInfoAdapter(CultureInfo baseCulture, IFormatProvider provider)
|
||||||
|
: base(baseCulture.LCID)
|
||||||
|
{
|
||||||
|
_provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object GetFormat(Type formatType)
|
||||||
|
{
|
||||||
|
return _provider.GetFormat(formatType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to parse the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T? TryParse<T>(string value) where T : struct
|
||||||
|
{
|
||||||
|
switch (Type.GetTypeCode(typeof(T)))
|
||||||
|
{
|
||||||
|
case TypeCode.Boolean:
|
||||||
|
return (T?)(object)TryParse<bool>(value, bool.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Byte:
|
||||||
|
return (T?)(object)TryParse<byte>(value, byte.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.DateTime:
|
||||||
|
return (T?)(object)TryParse<DateTime>(value, DateTime.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Decimal:
|
||||||
|
return (T?)(object)TryParse<decimal>(value, decimal.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Double:
|
||||||
|
return (T?)(object)TryParse<double>(value, double.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Int16:
|
||||||
|
return (T?)(object)TryParse<short>(value, short.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Int32:
|
||||||
|
return (T?)(object)TryParse<int>(value, int.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Int64:
|
||||||
|
return (T?)(object)TryParse<long>(value, long.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.SByte:
|
||||||
|
return (T?)(object)TryParse<sbyte>(value, sbyte.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.Single:
|
||||||
|
return (T?)(object)TryParse<float>(value, float.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.UInt16:
|
||||||
|
return (T?)(object)TryParse<ushort>(value, ushort.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.UInt32:
|
||||||
|
return (T?)(object)TryParse<uint>(value, uint.TryParse);
|
||||||
|
|
||||||
|
case TypeCode.UInt64:
|
||||||
|
return (T?)(object)TryParse<ulong>(value, ulong.TryParse);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException(string.Format("Cannot parse type '{0}'.", typeof(T).FullName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to parse the specified value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <param name="value">The value to be parsed.</param>
|
||||||
|
/// <param name="parse">The parse function.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static T? TryParse<T>(string value, TryParseDelegate<T> parse) where T : struct
|
||||||
|
{
|
||||||
|
T result;
|
||||||
|
return parse(value, out result) ? (T?)result : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines a method that is used to tentatively parse a string.
|
||||||
|
/// </summary>
|
||||||
|
public delegate bool TryParseDelegate<T>(string value, out T result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
namespace YamlDotNet.RepresentationModel.Serialization
|
namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instructs the <see cref="YamlSerializer"/> to use a different field name for serialization.
|
/// Instructs the <see cref="Deserializer"/> to use a different field name for serialization.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
|
||||||
public class YamlAliasAttribute : Attribute
|
public class YamlAliasAttribute : Attribute
|
||||||
|
|
|
@ -29,7 +29,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using YamlDotNet.Core;
|
using YamlDotNet.Core;
|
||||||
using YamlDotNet.Core.Events;
|
using YamlDotNet.Core.Events;
|
||||||
|
|
||||||
|
@ -39,6 +38,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads and writes objects from and to YAML.
|
/// Reads and writes objects from and to YAML.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("YamlSerializer has been replaced by Deserializer. This class will be removed in the next version.")]
|
||||||
public class YamlSerializer
|
public class YamlSerializer
|
||||||
{
|
{
|
||||||
private readonly YamlSerializerModes mode;
|
private readonly YamlSerializerModes mode;
|
||||||
|
@ -330,7 +330,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
}
|
}
|
||||||
|
|
||||||
object result = DeserializeValueNotNull(reader, context, nodeEvent, expectedType);
|
object result = DeserializeValueNotNull(reader, context, nodeEvent, expectedType);
|
||||||
return ObjectConverter.Convert(result, expectedType);
|
return TypeConverter.ChangeType(result, expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsNull(NodeEvent nodeEvent)
|
private bool IsNull(NodeEvent nodeEvent)
|
||||||
|
@ -468,7 +468,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TypeConverter converter = TypeDescriptor.GetConverter(type);
|
var converter = TypeDescriptor.GetConverter(type);
|
||||||
if (converter != null && converter.CanConvertFrom(typeof(string)))
|
if (converter != null && converter.CanConvertFrom(typeof(string)))
|
||||||
{
|
{
|
||||||
result = converter.ConvertFromInvariantString(scalar.Value);
|
result = converter.ConvertFromInvariantString(scalar.Value);
|
||||||
|
@ -790,6 +790,7 @@ namespace YamlDotNet.RepresentationModel.Serialization
|
||||||
/// on the user's code.
|
/// on the user's code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TSerialized">The type of the serialized.</typeparam>
|
/// <typeparam name="TSerialized">The type of the serialized.</typeparam>
|
||||||
|
[Obsolete("YamlSerializer has been replaced by Deserializer. This class will be removed in the next version.")]
|
||||||
public class YamlSerializer<TSerialized> : YamlSerializer
|
public class YamlSerializer<TSerialized> : YamlSerializer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
@ -102,6 +102,7 @@
|
||||||
<Compile Include="Serialization\ReadableAndWritablePropertiesTypeDescriptor.cs" />
|
<Compile Include="Serialization\ReadableAndWritablePropertiesTypeDescriptor.cs" />
|
||||||
<Compile Include="Serialization\ReadablePropertiesTypeDescriptor.cs" />
|
<Compile Include="Serialization\ReadablePropertiesTypeDescriptor.cs" />
|
||||||
<Compile Include="Serialization\Serializer.cs" />
|
<Compile Include="Serialization\Serializer.cs" />
|
||||||
|
<Compile Include="Serialization\TypeConverter.cs" />
|
||||||
<Compile Include="Serialization\WriterEventEmitter.cs" />
|
<Compile Include="Serialization\WriterEventEmitter.cs" />
|
||||||
<Compile Include="Serialization\EventInfo.cs" />
|
<Compile Include="Serialization\EventInfo.cs" />
|
||||||
<Compile Include="Serialization\FullObjectGraphTraversalStrategy.cs" />
|
<Compile Include="Serialization\FullObjectGraphTraversalStrategy.cs" />
|
||||||
|
@ -115,7 +116,6 @@
|
||||||
<Compile Include="Serialization\RoundtripObjectGraphTraversalStrategy.cs" />
|
<Compile Include="Serialization\RoundtripObjectGraphTraversalStrategy.cs" />
|
||||||
<Compile Include="Serialization\StreamFragment.cs" />
|
<Compile Include="Serialization\StreamFragment.cs" />
|
||||||
<Compile Include="Serialization\ObjectAnchorCollection.cs" />
|
<Compile Include="Serialization\ObjectAnchorCollection.cs" />
|
||||||
<Compile Include="Serialization\ObjectConverter.cs" />
|
|
||||||
<Compile Include="Serialization\TagMappings.cs" />
|
<Compile Include="Serialization\TagMappings.cs" />
|
||||||
<Compile Include="Serialization\TypeAssigningEventEmitter.cs" />
|
<Compile Include="Serialization\TypeAssigningEventEmitter.cs" />
|
||||||
<Compile Include="Serialization\YamlAliasAttribute.cs" />
|
<Compile Include="Serialization\YamlAliasAttribute.cs" />
|
||||||
|
@ -200,9 +200,5 @@
|
||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="Serialization\NodeDeserializers\" />
|
|
||||||
<Folder Include="Serialization\" />
|
|
||||||
<Folder Include="Serialization\NodeTypeResolvers\" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
|
@ -1,38 +0,0 @@
|
||||||
// This file is part of YamlDotNet - A .NET library for YAML.
|
|
||||||
// Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Antoine Aubry
|
|
||||||
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
// this software and associated documentation files (the "Software"), to deal in
|
|
||||||
// the Software without restriction, including without limitation the rights to
|
|
||||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
// of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
// so, subject to the following conditions:
|
|
||||||
|
|
||||||
// The above copyright notice and this permission notice shall be included in all
|
|
||||||
// copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
// SOFTWARE.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using Xunit;
|
|
||||||
using System.Drawing;
|
|
||||||
using YamlDotNet.RepresentationModel.Serialization;
|
|
||||||
|
|
||||||
namespace YamlDotNet.UnitTests.RepresentationModel
|
|
||||||
{
|
|
||||||
public class ObjectConverterTests
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void StringToColor()
|
|
||||||
{
|
|
||||||
Color color = ObjectConverter.Convert<string, Color>("white");
|
|
||||||
Assert.Equal(unchecked((int)0xFFFFFFFF), color.ToArgb());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -21,10 +21,9 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
||||||
[Fact]
|
[Fact]
|
||||||
public void NotSpecifyingObjectFactoryUsesDefault()
|
public void NotSpecifyingObjectFactoryUsesDefault()
|
||||||
{
|
{
|
||||||
var serializer = new YamlSerializer();
|
var deserializer = new Deserializer();
|
||||||
var options = new DeserializationOptions();
|
deserializer.RegisterTagMapping("!foo", typeof(FooBase));
|
||||||
options.Mappings.Add("!foo", typeof(FooBase));
|
var result = deserializer.Deserialize(new StringReader("!foo {}"));
|
||||||
var result = serializer.Deserialize(new StringReader("!foo {}"), options);
|
|
||||||
|
|
||||||
Assert.IsType<FooBase>(result);
|
Assert.IsType<FooBase>(result);
|
||||||
}
|
}
|
||||||
|
@ -32,13 +31,10 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
||||||
[Fact]
|
[Fact]
|
||||||
public void ObjectFactoryIsInvoked()
|
public void ObjectFactoryIsInvoked()
|
||||||
{
|
{
|
||||||
var serializer = new YamlSerializer();
|
var deserializer = new Deserializer(new LambdaObjectFactory(t => new FooDerived()));
|
||||||
var options = new DeserializationOptions();
|
deserializer.RegisterTagMapping("!foo", typeof(FooBase));
|
||||||
options.Mappings.Add("!foo", typeof(FooBase));
|
|
||||||
|
|
||||||
options.ObjectFactory = new LambdaObjectFactory(t => new FooDerived());
|
var result = deserializer.Deserialize(new StringReader("!foo {}"));
|
||||||
|
|
||||||
var result = serializer.Deserialize(new StringReader("!foo {}"), options);
|
|
||||||
|
|
||||||
Assert.IsType<FooDerived>(result);
|
Assert.IsType<FooDerived>(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,23 +459,28 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
||||||
Point value = (Point)result;
|
Point value = (Point)result;
|
||||||
Assert.Equal(10, value.X);
|
Assert.Equal(10, value.X);
|
||||||
Assert.Equal(20, value.Y);
|
Assert.Equal(20, value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DeserializeConvertible()
|
||||||
|
{
|
||||||
|
var serializer = new Deserializer();
|
||||||
|
object result = serializer.Deserialize(YamlFile("convertible.yaml"), typeof(Z));
|
||||||
|
|
||||||
|
Assert.True(typeof(Z).IsAssignableFrom(result.GetType()));
|
||||||
|
Assert.Equal("[hello, world]", ((Z)result).aaa);
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Fact]
|
public class Converter : System.ComponentModel.TypeConverter
|
||||||
//public void DeserializeConvertible()
|
|
||||||
//{
|
|
||||||
// YamlSerializer<Z> serializer = new YamlSerializer<Z>();
|
|
||||||
// object result = serializer.Deserialize(YamlFile("convertible.yaml"));
|
|
||||||
|
|
||||||
// Assert.True(typeof(Z).IsAssignableFrom(result.GetType()));
|
|
||||||
// Assert.Equal("[hello, world]", ((Z)result).aaa, "The property has the wrong value.");
|
|
||||||
//}
|
|
||||||
|
|
||||||
public class Converter : TypeConverter
|
|
||||||
{
|
{
|
||||||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
|
||||||
{
|
{
|
||||||
return sourceType == typeof(string);
|
return sourceType == typeof(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||||
|
@ -765,13 +770,7 @@ namespace YamlDotNet.UnitTests.RepresentationModel
|
||||||
|
|
||||||
Assert.Null(copy.MyString);
|
Assert.Null(copy.MyString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Fact]
|
|
||||||
//public void DeserializationIgnoresUnknownProperties()
|
|
||||||
//{
|
|
||||||
// var serializer = new YamlSerializer(typeof(X));
|
|
||||||
//}
|
|
||||||
|
|
||||||
class ContainsIgnore
|
class ContainsIgnore
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
@ -54,7 +54,6 @@
|
||||||
<Compile Include="Core\ParserTests.cs" />
|
<Compile Include="Core\ParserTests.cs" />
|
||||||
<Compile Include="Core\ScannerTests.cs" />
|
<Compile Include="Core\ScannerTests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="RepresentationModel\ObjectConverterTests.cs" />
|
|
||||||
<Compile Include="RepresentationModel\ObjectFactoryTests.cs" />
|
<Compile Include="RepresentationModel\ObjectFactoryTests.cs" />
|
||||||
<Compile Include="RepresentationModel\Samples.cs" />
|
<Compile Include="RepresentationModel\Samples.cs" />
|
||||||
<Compile Include="RepresentationModel\SerializationTests.cs" />
|
<Compile Include="RepresentationModel\SerializationTests.cs" />
|
||||||
|
|
Загрузка…
Ссылка в новой задаче