/ gbnf / src / limits / definitions.rs
definitions.rs
  1  use crate::AsGbnfComplex;
  2  use crate::AsGbnfLimit;
  3  use crate::AsGbnfPrimitive;
  4  use crate::GbnfLimit;
  5  
  6  pub trait GbnfLimitType {
  7      type Type;
  8  }
  9  
 10  pub trait GbnfLimitStructMarker {}
 11  
 12  macro_rules! define_limit_marker {
 13      ($field_type:ty, $value_type:ty) => {
 14          impl GbnfLimitType for $field_type {
 15              type Type = $value_type;
 16          }
 17      };
 18  }
 19  
 20  define_limit_marker!(String, String);
 21  define_limit_marker!(i32, i32);
 22  
 23  impl<T> GbnfLimitType for Vec<T>
 24  where
 25      T: GbnfLimitType,
 26  {
 27      type Type = <T as GbnfLimitType>::Type;
 28  }
 29  
 30  impl<T> GbnfLimitType for Option<T> {
 31      type Type = T;
 32  }
 33  
 34  pub trait GbnfLimitTypeContainer<T: GbnfLimitType> {
 35      type ContainerType;
 36  }
 37  
 38  impl GbnfLimitTypeContainer<String> for String {
 39      type ContainerType = Vec<String>;
 40  }
 41  
 42  impl GbnfLimitTypeContainer<i32> for i32 {
 43      type ContainerType = Vec<i32>;
 44  }
 45  
 46  impl<T: GbnfLimitType> GbnfLimitTypeContainer<T> for Vec<T> {
 47      type ContainerType = Vec<<T as GbnfLimitType>::Type>;
 48  }
 49  
 50  impl<T: GbnfLimitType + GbnfLimitTypeContainer<T>> GbnfLimitTypeContainer<Vec<T>> for Vec<T> {
 51      type ContainerType = <T as GbnfLimitTypeContainer<T>>::ContainerType;
 52  }
 53  
 54  impl<T: GbnfLimitType> GbnfLimitTypeContainer<T> for Option<T> {
 55      type ContainerType = <T as GbnfLimitType>::Type;
 56  }
 57  
 58  impl<T: GbnfLimitType> GbnfLimitTypeContainer<Option<T>> for Option<T> {
 59      type ContainerType = <T as GbnfLimitType>::Type;
 60  }
 61  
 62  pub struct GbnfLimitedPrimitive<T>
 63  where
 64      T: GbnfLimitType + GbnfLimitTypeContainer<T>,
 65  {
 66      field_type: std::marker::PhantomData<T>,
 67      values: <T as GbnfLimitTypeContainer<T>>::ContainerType,
 68  }
 69  
 70  impl<T> GbnfLimitedPrimitive<T>
 71  where
 72      T: GbnfLimitType + GbnfLimitTypeContainer<T>,
 73  {
 74      pub fn new(values: <T as GbnfLimitTypeContainer<T>>::ContainerType) -> GbnfLimitedPrimitive<T> {
 75          GbnfLimitedPrimitive {
 76              field_type: std::marker::PhantomData,
 77              values,
 78          }
 79      }
 80  }
 81  
 82  impl<T> AsGbnfLimit for GbnfLimitedPrimitive<T>
 83  where
 84      T: AsGbnfPrimitive
 85          + ToString
 86          + GbnfLimitTypeContainer<T, ContainerType = Vec<T>>
 87          + GbnfLimitType<Type = T>,
 88  {
 89      fn to_gbnf_limit(self) -> GbnfLimit {
 90          let vals = self.values.into_iter().map(|v| v.to_string());
 91          GbnfLimit::Simple(<T as AsGbnfPrimitive>::to_gbnf_primitive(), vals.collect())
 92      }
 93  }
 94  
 95  impl<T> AsGbnfLimit for GbnfLimitedPrimitive<Vec<T>>
 96  where
 97      T: AsGbnfPrimitive
 98          + ToString
 99          + GbnfLimitTypeContainer<T, ContainerType = Vec<T>>
100          + GbnfLimitType<Type = T>,
101      Vec<T>: GbnfLimitType,
102  {
103      fn to_gbnf_limit(self) -> GbnfLimit {
104          let vals = self.values.into_iter().map(|v| v.to_string());
105          GbnfLimit::Simple(<T as AsGbnfPrimitive>::to_gbnf_primitive(), vals.collect())
106      }
107  }
108  
109  pub struct GbnfLimitedComplex<T>
110  where
111      T: GbnfLimitType + GbnfLimitTypeContainer<T>,
112  {
113      field_type: std::marker::PhantomData<T>,
114      values: <T as GbnfLimitTypeContainer<T>>::ContainerType,
115  }
116  
117  impl<T> GbnfLimitedComplex<T>
118  where
119      T: GbnfLimitType + GbnfLimitTypeContainer<T>,
120  {
121      pub fn new(values: <T as GbnfLimitTypeContainer<T>>::ContainerType) -> GbnfLimitedComplex<T> {
122          GbnfLimitedComplex {
123              field_type: std::marker::PhantomData,
124              values,
125          }
126      }
127  }
128  
129  impl<T, U> AsGbnfLimit for GbnfLimitedComplex<T>
130  where
131      T: AsGbnfComplex + GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
132      U: AsGbnfLimit + GbnfLimitStructMarker,
133  {
134      fn to_gbnf_limit(self) -> GbnfLimit {
135          self.values.to_gbnf_limit()
136      }
137  }
138  
139  impl<T, U> AsGbnfLimit for GbnfLimitedComplex<Vec<T>>
140  where
141      T: AsGbnfComplex + GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
142      U: AsGbnfLimit + GbnfLimitStructMarker,
143  {
144      fn to_gbnf_limit(self) -> GbnfLimit {
145          self.values.to_gbnf_limit()
146      }
147  }
148  
149  impl<T, U> AsGbnfLimit for GbnfLimitedComplex<Option<T>>
150  where
151      T: GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
152      U: AsGbnfLimit + GbnfLimitStructMarker,
153  {
154      fn to_gbnf_limit(self) -> GbnfLimit {
155          self.values.to_gbnf_limit()
156      }
157  }