cgp_field/impls/
build_from.rs

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