cgp_field/impls/
build_from.rs1use 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}