ai-game/gbnf/src/limits/definitions.rs

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()
}
}