using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Capnp
{
///
/// Provides functionality to construct domain objects from .
///
public static class CapnpSerializable
{
interface IConstructibleFromDeserializerState
{
T Create(DeserializerState state);
}
class FromStruct: IConstructibleFromDeserializerState
where T : ICapnpSerializable, new()
{
public T Create(DeserializerState state)
{
var result = new T();
if (state.Kind != ObjectKind.Nil)
{
result.Deserialize(state);
}
return result;
}
}
class FromList: IConstructibleFromDeserializerState>
where T: class
{
readonly Func _elementSerializer;
public FromList()
{
_elementSerializer = (Func)GetSerializer(typeof(T));
}
public IReadOnlyList Create(DeserializerState state)
{
return state.RequireList().Cast(_elementSerializer);
}
}
class FromCapability: IConstructibleFromDeserializerState
where T: class
{
public T Create(DeserializerState state)
{
return state.RequireCap();
}
}
static readonly ConditionalWeakTable> _typeMap =
new ConditionalWeakTable>();
static CapnpSerializable()
{
_typeMap.Add(typeof(string), d => d.RequireList().CastText());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastBool());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastSByte());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastByte());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastShort());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastUShort());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastInt());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastUInt());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastLong());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastULong());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastFloat());
_typeMap.Add(typeof(IReadOnlyList), d => d.RequireList().CastDouble());
}
static Func CreateSerializer(Type type)
{
if (typeof(ICapnpSerializable).IsAssignableFrom(type))
{
try
{
return ((IConstructibleFromDeserializerState