Skip to content

Commit

Permalink
Merge branch 'type-serialization'
Browse files Browse the repository at this point in the history
  • Loading branch information
aaubry committed Jan 26, 2018
2 parents 42bf5ff + ddad0eb commit 05b6e27
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 22 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.

# Changelog

## Version 4.3.0

* Add support for (de)serialization of System.Type

## Version 4.2.4

* Refactored the project and solution so that they load and build cleanly in VS2017.
Expand Down
54 changes: 41 additions & 13 deletions YamlDotNet.Test/Serialization/SerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,21 +1488,21 @@ static Exception GetExceptionWithStackTrace()
public void RegisteringATypeConverterPreventsTheTypeFromBeingVisited()
{
var serializer = new SerializerBuilder()
.WithTypeConverter(new SystemTypeTypeConverter())
.WithTypeConverter(new NonSerializableTypeConverter())
.Build();

var yaml = serializer.Serialize(new TypeContainer
var yaml = serializer.Serialize(new NonSerializableContainer
{
Type = typeof(string),
Value = new NonSerializable { Text = "hello" },
});

var deserializer = new DeserializerBuilder()
.WithTypeConverter(new SystemTypeTypeConverter())
.WithTypeConverter(new NonSerializableTypeConverter())
.Build();

var result = deserializer.Deserialize<TypeContainer>(yaml);
var result = deserializer.Deserialize<NonSerializableContainer>(yaml);

Assert.Equal(typeof(string), result.Type);
Assert.Equal("hello", result.Value.Text);
}

[Fact]
Expand Down Expand Up @@ -1531,34 +1531,62 @@ public void NamingConventionIsNotAppliedByDeserializerWhenApplyNamingConventions
Assert.Equal("value", parsed.NoConvention);
}

[Fact]
public void TypesAreSerializable()
{
var sut = new SerializerBuilder()
.Build();

var yaml = sut.Serialize(typeof(string));

Assert.Contains(typeof(string).AssemblyQualifiedName, yaml);
}

[Fact]
public void TypesAreDeserializable()
{
var sut = new DeserializerBuilder()
.Build();

var type = sut.Deserialize<Type>(typeof(string).AssemblyQualifiedName);

Assert.Equal(typeof(string), type);
}

public class NamingConventionDisabled
{
[YamlMember(ApplyNamingConventions = false)]
public string NoConvention { get; set; }
}

public class TypeContainer
public class NonSerializableContainer
{
public Type Type { get; set; }
public NonSerializable Value { get; set; }
}

public class NonSerializable
{
public string WillThrow { get { throw new Exception(); } }

public string Text { get; set; }
}

public class SystemTypeTypeConverter : IYamlTypeConverter
public class NonSerializableTypeConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
return typeof(Type).IsAssignableFrom(type);
return typeof(NonSerializable).IsAssignableFrom(type);
}

public object ReadYaml(IParser parser, Type type)
{
var scalar = parser.Expect<Scalar>();
return Type.GetType(scalar.Value);
return new NonSerializable { Text = scalar.Value };
}

public void WriteYaml(IEmitter emitter, object value, Type type)
{
var typeName = ((Type)value).AssemblyQualifiedName;
emitter.Emit(new Scalar(typeName));
emitter.Emit(new Scalar(((NonSerializable)value).Text));
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion YamlDotNet/Serialization/BuilderSkeleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.TypeInspectors;
using System.Linq.Expressions;

namespace YamlDotNet.Serialization
{
Expand All @@ -45,6 +45,7 @@ internal BuilderSkeleton()

typeConverterFactories = new LazyComponentRegistrationList<Nothing, IYamlTypeConverter>();
typeConverterFactories.Add(typeof(GuidConverter), _ => new GuidConverter(false));
typeConverterFactories.Add(typeof(SystemTypeConverter), _ => new SystemTypeConverter());

typeInspectorFactories = new LazyComponentRegistrationList<ITypeInspector, ITypeInspector>();
}
Expand Down
18 changes: 10 additions & 8 deletions YamlDotNet/Serialization/Converters/GuidConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

using System;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;

namespace YamlDotNet.Serialization.Converters
{
Expand All @@ -35,22 +37,22 @@ public GuidConverter(bool jsonCompatible)
this.jsonCompatible = jsonCompatible;
}

public bool Accepts(System.Type type)
public bool Accepts(Type type)
{
return type == typeof(System.Guid);
return type == typeof(Guid);
}

public object ReadYaml(Core.IParser parser, System.Type type)
public object ReadYaml(IParser parser, Type type)
{
var value = ((Core.Events.Scalar)parser.Current).Value;
var value = ((Scalar)parser.Current).Value;
parser.MoveNext();
return new System.Guid(value);
return new Guid(value);
}

public void WriteYaml(Core.IEmitter emitter, object value, System.Type type)
public void WriteYaml(IEmitter emitter, object value, Type type)
{
var guid = (System.Guid)value;
emitter.Emit(new Core.Events.Scalar(null, null, guid.ToString("D"), jsonCompatible ? ScalarStyle.DoubleQuoted : ScalarStyle.Any, true, false));
var guid = (Guid)value;
emitter.Emit(new Scalar(null, null, guid.ToString("D"), jsonCompatible ? ScalarStyle.DoubleQuoted : ScalarStyle.Any, true, false));
}
}
}
33 changes: 33 additions & 0 deletions YamlDotNet/Serialization/Converters/SystemTypeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;

namespace YamlDotNet.Serialization.Converters
{
/// <summary>
/// Converter for System.Type.
/// </summary>
/// <remarks>
/// Converts <see cref="System.Type" /> to a scalar containing the assembly qualified name of the type.
/// </remarks>
public class SystemTypeConverter : IYamlTypeConverter
{
public bool Accepts(Type type)
{
return typeof(Type).IsAssignableFrom(type);
}

public object ReadYaml(IParser parser, Type type)
{
var value = ((Scalar)parser.Current).Value;
parser.MoveNext();
return Type.GetType(value, throwOnError: true);
}

public void WriteYaml(IEmitter emitter, object value, Type type)
{
var systemType = (Type)value;
emitter.Emit(new Scalar(null, null, systemType.AssemblyQualifiedName, ScalarStyle.Any, true, false));
}
}
}
1 change: 1 addition & 0 deletions YamlDotNet/Serialization/Deserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public BackwardsCompatibleConfiguration(

converters = new List<IYamlTypeConverter>();
converters.Add(new GuidConverter(false));
converters.Add(new SystemTypeConverter());

NodeDeserializers = new List<INodeDeserializer>();
NodeDeserializers.Add(new YamlConvertibleNodeDeserializer(objectFactory));
Expand Down
1 change: 1 addition & 0 deletions YamlDotNet/Serialization/Serializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public BackwardsCompatibleConfiguration(SerializationOptions options, INamingCon

Converters = new List<IYamlTypeConverter>();
Converters.Add(new GuidConverter(IsOptionSet(SerializationOptions.JsonCompatible)));
Converters.Add(new SystemTypeConverter());

typeResolver = IsOptionSet(SerializationOptions.DefaultToStaticType)
? (ITypeResolver)new StaticTypeResolver()
Expand Down

0 comments on commit 05b6e27

Please sign in to comment.