158 lines
4.0 KiB
Rust
158 lines
4.0 KiB
Rust
use crate::AsGbnfComplex;
|
|
use crate::AsGbnfLimit;
|
|
use crate::AsGbnfPrimitive;
|
|
use crate::GbnfLimit;
|
|
|
|
pub trait GbnfLimitType {
|
|
type Type;
|
|
}
|
|
|
|
pub trait GbnfLimitStructMarker {}
|
|
|
|
macro_rules! define_limit_marker {
|
|
($field_type:ty, $value_type:ty) => {
|
|
impl GbnfLimitType for $field_type {
|
|
type Type = $value_type;
|
|
}
|
|
};
|
|
}
|
|
|
|
define_limit_marker!(String, String);
|
|
define_limit_marker!(i32, i32);
|
|
|
|
impl<T> GbnfLimitType for Vec<T>
|
|
where
|
|
T: GbnfLimitType,
|
|
{
|
|
type Type = <T as GbnfLimitType>::Type;
|
|
}
|
|
|
|
impl<T> GbnfLimitType for Option<T> {
|
|
type Type = T;
|
|
}
|
|
|
|
pub trait GbnfLimitTypeContainer<T: GbnfLimitType> {
|
|
type ContainerType;
|
|
}
|
|
|
|
impl GbnfLimitTypeContainer<String> for String {
|
|
type ContainerType = Vec<String>;
|
|
}
|
|
|
|
impl GbnfLimitTypeContainer<i32> for i32 {
|
|
type ContainerType = Vec<i32>;
|
|
}
|
|
|
|
impl<T: GbnfLimitType> GbnfLimitTypeContainer<T> for Vec<T> {
|
|
type ContainerType = Vec<<T as GbnfLimitType>::Type>;
|
|
}
|
|
|
|
impl<T: GbnfLimitType + GbnfLimitTypeContainer<T>> GbnfLimitTypeContainer<Vec<T>> for Vec<T> {
|
|
type ContainerType = <T as GbnfLimitTypeContainer<T>>::ContainerType;
|
|
}
|
|
|
|
impl<T: GbnfLimitType> GbnfLimitTypeContainer<T> for Option<T> {
|
|
type ContainerType = <T as GbnfLimitType>::Type;
|
|
}
|
|
|
|
impl<T: GbnfLimitType> GbnfLimitTypeContainer<Option<T>> for Option<T> {
|
|
type ContainerType = <T as GbnfLimitType>::Type;
|
|
}
|
|
|
|
pub struct GbnfLimitedPrimitive<T>
|
|
where
|
|
T: GbnfLimitType + GbnfLimitTypeContainer<T>,
|
|
{
|
|
field_type: std::marker::PhantomData<T>,
|
|
values: <T as GbnfLimitTypeContainer<T>>::ContainerType,
|
|
}
|
|
|
|
impl<T> GbnfLimitedPrimitive<T>
|
|
where
|
|
T: GbnfLimitType + GbnfLimitTypeContainer<T>,
|
|
{
|
|
pub fn new(values: <T as GbnfLimitTypeContainer<T>>::ContainerType) -> GbnfLimitedPrimitive<T> {
|
|
GbnfLimitedPrimitive {
|
|
field_type: std::marker::PhantomData,
|
|
values,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T> AsGbnfLimit for GbnfLimitedPrimitive<T>
|
|
where
|
|
T: AsGbnfPrimitive
|
|
+ ToString
|
|
+ GbnfLimitTypeContainer<T, ContainerType = Vec<T>>
|
|
+ GbnfLimitType<Type = T>,
|
|
{
|
|
fn to_gbnf_limit(self) -> GbnfLimit {
|
|
let vals = self.values.into_iter().map(|v| v.to_string());
|
|
GbnfLimit::Simple(<T as AsGbnfPrimitive>::to_gbnf_primitive(), vals.collect())
|
|
}
|
|
}
|
|
|
|
impl<T> AsGbnfLimit for GbnfLimitedPrimitive<Vec<T>>
|
|
where
|
|
T: AsGbnfPrimitive
|
|
+ ToString
|
|
+ GbnfLimitTypeContainer<T, ContainerType = Vec<T>>
|
|
+ GbnfLimitType<Type = T>,
|
|
Vec<T>: GbnfLimitType,
|
|
{
|
|
fn to_gbnf_limit(self) -> GbnfLimit {
|
|
let vals = self.values.into_iter().map(|v| v.to_string());
|
|
GbnfLimit::Simple(<T as AsGbnfPrimitive>::to_gbnf_primitive(), vals.collect())
|
|
}
|
|
}
|
|
|
|
pub struct GbnfLimitedComplex<T>
|
|
where
|
|
T: GbnfLimitType + GbnfLimitTypeContainer<T>,
|
|
{
|
|
field_type: std::marker::PhantomData<T>,
|
|
values: <T as GbnfLimitTypeContainer<T>>::ContainerType,
|
|
}
|
|
|
|
impl<T> GbnfLimitedComplex<T>
|
|
where
|
|
T: GbnfLimitType + GbnfLimitTypeContainer<T>,
|
|
{
|
|
pub fn new(values: <T as GbnfLimitTypeContainer<T>>::ContainerType) -> GbnfLimitedComplex<T> {
|
|
GbnfLimitedComplex {
|
|
field_type: std::marker::PhantomData,
|
|
values,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, U> AsGbnfLimit for GbnfLimitedComplex<T>
|
|
where
|
|
T: AsGbnfComplex + GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
|
|
U: AsGbnfLimit + GbnfLimitStructMarker,
|
|
{
|
|
fn to_gbnf_limit(self) -> GbnfLimit {
|
|
self.values.to_gbnf_limit()
|
|
}
|
|
}
|
|
|
|
impl<T, U> AsGbnfLimit for GbnfLimitedComplex<Vec<T>>
|
|
where
|
|
T: AsGbnfComplex + GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
|
|
U: AsGbnfLimit + GbnfLimitStructMarker,
|
|
{
|
|
fn to_gbnf_limit(self) -> GbnfLimit {
|
|
self.values.to_gbnf_limit()
|
|
}
|
|
}
|
|
|
|
impl<T, U> AsGbnfLimit for GbnfLimitedComplex<Option<T>>
|
|
where
|
|
T: GbnfLimitType<Type = U> + GbnfLimitTypeContainer<T, ContainerType = U>,
|
|
U: AsGbnfLimit + GbnfLimitStructMarker,
|
|
{
|
|
fn to_gbnf_limit(self) -> GbnfLimit {
|
|
self.values.to_gbnf_limit()
|
|
}
|
|
}
|