using System; using System.Collections; using System.Collections.Generic; namespace Capnp { /// <summary> /// ListDeserializer specialization for a list of capabilities. /// </summary> /// <typeparam name="T">Capability interface</typeparam> public class ListOfCapsDeserializer<T> : ListDeserializer, IReadOnlyList<T> where T: class { internal ListOfCapsDeserializer(in DeserializerState state) : base(state) { Rpc.CapabilityReflection.ValidateCapabilityInterface(typeof(T)); } /// <summary> /// Returns the capability at given index. /// </summary> /// <param name="index">Element index</param> /// <returns>The capability at given index (in terms of its proxy instance)</returns> public T this[int index] { get { if (index < 0 || index >= Count) throw new IndexOutOfRangeException(); return (Rpc.CapabilityReflection.CreateProxy<T>(State.DecodeCapPointer(index)) as T)!; } } /// <summary> /// Always ListKind.ListOfPointers /// </summary> public override ListKind Kind => ListKind.ListOfPointers; /// <summary> /// Always throws <see cref="NotSupportedException"/>, since it is not intended to convert a capability list to anything else. /// </summary> public override IReadOnlyList<T1> Cast<T1>(Func<DeserializerState, T1> cons) { throw new NotSupportedException("Cannot cast a list of capabilities to anything else"); } IEnumerable<T> Enumerate() { int count = Count; for (int i = 0; i < count; i++) { yield return this[i]; } } /// <summary> /// Implements <see cref="IEnumerable{T}"/>. /// </summary> /// <returns></returns> public IEnumerator<T> GetEnumerator() { return Enumerate().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }