cgp_field/impls/
build_from.rs1use core::marker::PhantomData;
2
3use crate::traits::{BuildField, HasFields, IntoBuilder, TakeField};
4use crate::types::{Cons, Field, Nil};
5
6pub trait CanBuildFrom<Source> {
7 type Output;
8
9 fn build_from(self, source: Source) -> Self::Output;
10}
11
12impl<Builder, Source, Output> CanBuildFrom<Source> for Builder
13where
14 Source: HasFields + IntoBuilder,
15 Source::Fields: FieldsBuilder<Source::Builder, Builder, Output = Output>,
16{
17 type Output = Output;
18
19 fn build_from(self, source: Source) -> Output {
20 Source::Fields::build_fields(source.into_builder(), self)
21 }
22}
23
24trait FieldsBuilder<Source, Target> {
25 type Output;
26
27 fn build_fields(source: Source, target: Target) -> Self::Output;
28}
29
30impl<Source, Target, RestFields, Tag, Value> FieldsBuilder<Source, Target>
31 for Cons<Field<Tag, Value>, RestFields>
32where
33 Source: TakeField<Tag, Value = Value>,
34 Target: BuildField<Tag, Value = Value>,
35 RestFields: FieldsBuilder<Source::Remainder, Target::Output>,
36{
37 type Output = RestFields::Output;
38
39 fn build_fields(source: Source, target: Target) -> Self::Output {
40 let (value, next_source) = source.take_field(PhantomData);
41 let next_target = target.build_field(PhantomData, value);
42
43 RestFields::build_fields(next_source, next_target)
44 }
45}
46
47impl<Source, Target> FieldsBuilder<Source, Target> for Nil {
48 type Output = Target;
49
50 fn build_fields(_source: Source, target: Target) -> Self::Output {
51 target
52 }
53}