Skip to main content

kv_derive_impl/
consumer.rs

1use std::marker::PhantomData;
2
3/// Responsible for consuming the scalar value and modifying itself accordingly.
4pub trait Consumer: Sized {
5    /// Defines the scalar representation type.
6    type Repr;
7
8    type Target;
9
10    fn init(&self, value: Self::Repr) -> Self::Target;
11
12    /// Consume or accumulate the new value into itself.
13    ///
14    /// May consume one or more entries.
15    fn consume(&self, target: &mut Self::Target, value: Self::Repr);
16}
17
18pub struct ScalarConsumer<T>(pub PhantomData<T>);
19
20impl<T> Consumer for ScalarConsumer<T> {
21    type Repr = T;
22    type Target = T;
23
24    #[inline]
25    fn init(&self, value: Self::Repr) -> Self::Target {
26        value
27    }
28
29    #[inline]
30    fn consume(&self, target: &mut Self::Target, value: Self::Repr) {
31        *target = value;
32    }
33}
34
35pub struct OptionConsumer<T: Consumer>(pub T);
36
37impl<T: Consumer> Consumer for OptionConsumer<T> {
38    type Repr = T::Repr;
39    type Target = Option<T::Target>;
40
41    #[inline]
42    fn init(&self, value: Self::Repr) -> Self::Target {
43        Some(self.0.init(value))
44    }
45
46    #[inline]
47    fn consume(&self, target: &mut Self::Target, value: Self::Repr) {
48        *target = self.init(value);
49    }
50}
51
52pub struct CollectionConsumer<T: Consumer>(pub T);
53
54impl<T: Consumer> Consumer for CollectionConsumer<T> {
55    type Repr = T::Repr;
56    type Target = Vec<T::Target>;
57
58    #[inline]
59    fn init(&self, value: Self::Repr) -> Self::Target {
60        vec![self.0.init(value)]
61    }
62
63    #[inline]
64    fn consume(&self, target: &mut Self::Target, value: Self::Repr) {
65        target.push(self.0.init(value));
66    }
67}