1use std::marker::PhantomData;
15
16use access::DataIndex;
17use cons::*;
18use fieldlist::*;
19use label::{LVCons, SelfValued, TypedValue, Valued};
20use view::{AssocDataIndexConsOf, DataIndexCons};
21
22#[derive(Debug, Clone)]
24pub struct Implemented;
25#[derive(Debug, Clone)]
28pub struct Unimplemented;
29
30#[derive(Debug, Clone)]
33pub struct Capabilities<DType, Fun, IsImpl> {
34 _marker: PhantomData<(DType, Fun, IsImpl)>,
35}
36
37#[derive(Debug, Clone)]
41pub struct StorageCapabilities<DType, DI, Fun, IsImpl>
42where
43 DI: DataIndex<DType = DType>,
44{
45 _marker: PhantomData<Capabilities<DType, Fun, IsImpl>>,
46 data: DI,
47}
48impl<'a, DType, DI, Fun, IsImpl> SelfValued for StorageCapabilities<DType, DI, Fun, IsImpl> where
49 DI: DataIndex<DType = DType>
50{
51}
52
53pub type StorageCapabilitiesCons<Label, DType, DI, Fun, IsImpl, Tail> =
55 LVCons<Label, StorageCapabilities<DType, DI, Fun, IsImpl>, Tail>;
56
57pub trait IsImplemented<Fun> {
59 type IsImpl;
63}
64
65pub trait PartialMap<F> {
67 type Output;
69 fn map(&self, f: &mut F) -> Self::Output;
71}
72impl<'a, F> PartialMap<F> for Nil {
73 type Output = Nil;
74 fn map(&self, _f: &mut F) -> Nil {
75 Nil
76 }
77}
78impl<'a, Label, DType, DI, Fun, Tail, F> PartialMap<F>
79 for StorageCapabilitiesCons<Label, DType, DI, Fun, Implemented, Tail>
80where
81 Tail: PartialMap<F>,
82 F: Func<DType>,
83 DI: DataIndex<DType = DType>,
84{
85 type Output = FieldPayloadCons<Label, DType, F::Output, Tail::Output>;
86
87 fn map(&self, f: &mut F) -> Self::Output {
88 FieldPayloadCons {
89 head: TypedValue::from(f.call(&self.head.value_ref().data)).into(),
90 tail: self.tail.map(f),
91 }
92 }
93}
94impl<'a, Label, DType, DI, Fun, Tail, F> PartialMap<F>
95 for StorageCapabilitiesCons<Label, DType, DI, Fun, Unimplemented, Tail>
96where
97 Tail: PartialMap<F>,
98 DI: DataIndex<DType = DType>,
99 F: FuncDefault,
100{
101 type Output = FieldPayloadCons<Label, DType, F::Output, Tail::Output>;
102
103 fn map(&self, f: &mut F) -> Self::Output {
104 FieldPayloadCons {
105 head: TypedValue::from(f.call()).into(),
106 tail: self.tail.map(f),
107 }
108 }
109}
110
111pub trait Func<DType> {
113 type Output;
115 fn call<DI>(&mut self, data: &DI) -> Self::Output
117 where
118 DI: DataIndex<DType = DType>;
119}
120
121pub trait FuncDefault {
123 type Output;
125 fn call(&mut self) -> Self::Output;
127}
128
129pub trait DeriveCapabilities<F> {
133 type Output: PartialMap<F>;
136
137 fn derive(self) -> Self::Output;
139}
140impl<F> DeriveCapabilities<F> for Nil {
141 type Output = Nil;
142 fn derive(self) -> Nil {
143 Nil
144 }
145}
146impl<Label, DType, DI, Tail, F> DeriveCapabilities<F> for DataIndexCons<Label, DType, DI, Tail>
147where
148 Tail: DeriveCapabilities<F>,
149 DI: DataIndex<DType = DType> + SelfValued,
150 DType: IsImplemented<F>,
151 StorageCapabilitiesCons<
152 Label,
153 DType,
154 DI,
155 F,
156 <DType as IsImplemented<F>>::IsImpl,
157 <Tail as DeriveCapabilities<F>>::Output,
158 >: PartialMap<F>,
159{
160 type Output = StorageCapabilitiesCons<
161 Label,
162 DType,
163 DI,
164 F,
165 <DType as IsImplemented<F>>::IsImpl,
166 <Tail as DeriveCapabilities<F>>::Output,
167 >;
168 fn derive(self) -> Self::Output {
169 LVCons {
170 head: StorageCapabilities {
171 data: self.head.value(),
172 _marker: PhantomData,
173 }
174 .into(),
175 tail: self.tail.derive(),
176 }
177 }
178}
179
180pub type DeriveCapabilitiesOf<Labels, Frames, F> =
184 <AssocDataIndexConsOf<Labels, Frames> as DeriveCapabilities<F>>::Output;