Skip to content

Commit

Permalink
Added support for ImmutableLists
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike-E-angelo committed Dec 3, 2020
1 parent 787bfb8 commit 226d766
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public override IEnumerator<ISerializerExtension> GetEnumerator()
yield return new AllowedMemberValuesExtension();
yield return new MemberFormatExtension();
yield return ImmutableArrayExtension.Default;
yield return ImmutableListExtension.Default;
yield return SerializationExtension.Default;
yield return NullableStructureAwareExtension.Default;
yield return new CustomSerializationExtension();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using ExtendedXmlSerializer.ContentModel;
using ExtendedXmlSerializer.ContentModel.Collections;
using ExtendedXmlSerializer.ContentModel.Content;
using ExtendedXmlSerializer.ContentModel.Format;
using ExtendedXmlSerializer.ContentModel.Identification;
using ExtendedXmlSerializer.ContentModel.Reflection;
using ExtendedXmlSerializer.Core;
using ExtendedXmlSerializer.Core.Specifications;
using ExtendedXmlSerializer.ReflectionModel;
using JetBrains.Annotations;
using System.Collections.Immutable;
using System.Collections.ObjectModel;
using System.Reflection;

namespace ExtendedXmlSerializer.ExtensionModel.Types
{
sealed class ImmutableListExtension : ISerializerExtension
{
public static ImmutableListExtension Default { get; } = new ImmutableListExtension();

ImmutableListExtension() : this(new IsAssignableGenericSpecification(typeof(ImmutableList<>))) {}

readonly ISpecification<TypeInfo> _specification;

public ImmutableListExtension(ISpecification<TypeInfo> specification) => _specification = specification;

public IServiceRepository Get(IServiceRepository parameter)
=> parameter.DecorateContentsWith<ImmutableLists>()
.When(_specification)
.Decorate<IGenericTypes, GenericTypes>();

void ICommand<IServices>.Execute(IServices parameter) {}

sealed class GenericTypes : IGenericTypes
{
readonly static TypeInfo Check = typeof(ImmutableList).GetTypeInfo();
readonly static ImmutableArray<TypeInfo> Type = typeof(ImmutableList<>).GetTypeInfo()
.Yield()
.ToImmutableArray();

readonly IGenericTypes _types;

public GenericTypes(IGenericTypes types) => _types = types;

public ImmutableArray<TypeInfo> Get(IIdentity parameter)
{
var type = _types.Get(parameter);
var result = Equals(type.Only(), Check) ? Type : type;
return result;
}
}

sealed class ImmutableLists : Collections
{
public ImmutableLists(RuntimeSerializers serializers, Contents contents) : base(serializers, contents) {}
}

sealed class Contents : ICollectionContents
{
readonly IInnerContentServices _contents;
readonly IEnumerators _enumerators;

public Contents(IInnerContentServices contents, IEnumerators enumerators)
{
_contents = contents;
_enumerators = enumerators;
}

public ISerializer Get(CollectionContentInput parameter)
=> new Serializer(Readers.Instance.Get(parameter.ItemType)(_contents, parameter.Item),
new EnumerableWriter(_enumerators, parameter.Item).Adapt());

sealed class Readers : Generic<IInnerContentServices, IReader, IReader>
{
public static Readers Instance { get; } = new Readers();

Readers() : base(typeof(Reader<>)) {}
}

sealed class Reader<T> : IReader
{
readonly IReader<Collection<T>> _reader;

[UsedImplicitly]
public Reader(IInnerContentServices services, IReader item)
: this(services.CreateContents<Collection<T>>(new CollectionInnerContentHandler(item, services))) {}

Reader(IReader<Collection<T>> reader) => _reader = reader;

public object Get(IFormatReader parameter) => _reader.Get(parameter).ToImmutableList();
}
}
}
}
25 changes: 25 additions & 0 deletions test/ExtendedXmlSerializer.Tests.ReportedIssues/Issue485Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using ExtendedXmlSerializer.Configuration;
using ExtendedXmlSerializer.Tests.ReportedIssues.Support;
using FluentAssertions;
using System.Collections.Immutable;
using Xunit;

namespace ExtendedXmlSerializer.Tests.ReportedIssues
{
public sealed class Issue485Tests
{
[Fact]
public void Verify()
{
var instance = new[] { 1, 2, 3, 4 }.ToImmutableList();

var serializer = new ConfigurationContainer().UseAutoFormatting()
.UseOptimizedNamespaces()
.EnableParameterizedContentWithPropertyAssignments()
.Create()
.ForTesting();

serializer.Cycle(instance).Should().BeEquivalentTo(instance);
}
}
}

0 comments on commit 226d766

Please sign in to comment.