#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IPA.Config.Data;
using IPA.Logging;
namespace IPA.Config.Stores.Converters
{
///
/// A base class for all type converters, providing most of the functionality.
///
/// the type of the items in the collection
/// the instantiated type of collection
public class CollectionConverter : ValueConverter
where TCollection : ICollection
{
///
/// Creates a using the default converter for the
/// element type. Equivalent to calling
/// with .
///
///
public CollectionConverter() : this(Converter.Default) { }
///
/// Creates a using the specified underlying converter.
///
/// the to use to convert the values
public CollectionConverter(ValueConverter underlying)
=> BaseConverter = underlying;
///
/// Gets the converter for the collection's value type.
///
protected ValueConverter BaseConverter { get; }
///
/// Creates a collection of type using the and
/// .
///
/// the initial size of the collecion
/// the object that will own the new collection
/// a new instance of
///
protected virtual TCollection Create(int size, object parent)
=> Activator.CreateInstance();
///
/// Populates the colleciton with the deserialized values from
/// with the parent .
///
/// the collection to populate
/// the values to populate it with
/// the object that will own the new objects
///
protected void PopulateFromValue(TCollection col, List list, object parent)
{
if (list is null) throw new ArgumentNullException(nameof(list));
foreach (var it in list)
col.Add(BaseConverter.FromValue(it, parent));
}
///
/// Deserializes a in into a new
/// owned by .
///
/// the to convert to a
/// the object that will own the resulting
/// a new holding the deserialized content of
///
public override TCollection FromValue(Value? value, object parent)
{
if (value is not List list) throw new ArgumentException("Argument not a List", nameof(value));
var col = Create(list.Count, parent);
PopulateFromValue(col, list, parent);
return col;
}
///
/// Serializes a into a .
///
/// the to serialize
/// the object owning
/// the that was serialized into
///
public override Value? ToValue(TCollection? obj, object parent)
=> Value.From(obj.Select(t => BaseConverter.ToValue(t, parent)));
}
///
/// A which default constructs a converter for use as the value converter.
///
/// the value type of the collection
/// the type of the colleciton
/// the type of the converter to use for
///
public sealed class CollectionConverter : CollectionConverter
where TCollection : ICollection
where TConverter : ValueConverter, new()
{
///
/// Creates a using a default constructed
/// element type. Equivalent to calling
/// with a default-constructed .
///
///
public CollectionConverter() : base(new TConverter()) { }
}
#if NET4
///
/// A for an , creating a when deserializing.
///
/// the element type of the
///
public class ISetConverter : CollectionConverter>
{
///
/// Creates an using the default converter for .
///
///
public ISetConverter() : base() { }
///
/// Creates an using the specified underlying converter for values.
///
/// the underlying to use for the values
public ISetConverter(ValueConverter underlying) : base(underlying) { }
///
/// Creates a new (a ) for deserialization.
///
/// the size to initialize it to
/// the object that will own the new object
/// the new
protected override ISet Create(int size, object parent)
=> new HashSet();
}
///
/// An which default constructs a converter for use as the value converter.
///
/// the value type of the collection
/// the type of the converter to use for
///
public sealed class ISetConverter : ISetConverter
where TConverter : ValueConverter, new()
{
///
/// Creates an using a default constructed
/// element type. Equivalent to calling
/// with a default-constructed .
///
///
public ISetConverter() : base(new TConverter()) { }
}
#endif
///
/// A for a .
///
/// the element type of the
///
public class ListConverter : CollectionConverter>
{
///
/// Creates an using the default converter for .
///
///
public ListConverter() : base() { }
///
/// Creates an using the specified underlying converter for values.
///
/// the underlying to use for the values
public ListConverter(ValueConverter underlying) : base(underlying) { }
///
/// Creates a new for deserialization.
///
/// the size to initialize it to
/// the object that will own the new object
/// the new
protected override List Create(int size, object parent)
=> new(size);
}
///
/// A which default constructs a converter for use as the value converter.
///
/// the value type of the collection
/// the type of the converter to use for
///
public sealed class ListConverter : ListConverter
where TConverter : ValueConverter, new()
{
///
/// Creates an using a default constructed
/// element type. Equivalent to calling
/// with a default-constructed .
///
///
public ListConverter() : base(new TConverter()) { }
}
///
/// A for an , creating a when deserializing.
///
/// the element type of the
///
public class IListConverter : CollectionConverter>
{
///
/// Creates an using the default converter for .
///
///
public IListConverter() : base() { }
///
/// Creates an using the specified underlying converter for values.
///
/// the underlying to use for the values
public IListConverter(ValueConverter underlying) : base(underlying) { }
///
/// Creates a new (a ) for deserialization.
///
/// the size to initialize it to
/// the object that will own the new object
/// the new
protected override IList Create(int size, object parent)
=> new List(size);
}
///
/// An which default constructs a converter for use as the value converter.
///
/// the value type of the collection
/// the type of the converter to use for
///
public sealed class IListConverter : IListConverter
where TConverter : ValueConverter, new()
{
///
/// Creates an using a default constructed
/// element type. Equivalent to calling
/// with a default-constructed .
///
///
public IListConverter() : base(new TConverter()) { }
}
}