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 }