Use strings in type-level rust programming.
Find a file
2026-08-11 13:12:46 +02:00
macros rename types for more consistency and add typenames 2026-08-11 13:12:46 +02:00
src rename types for more consistency and add typenames 2026-08-11 13:12:46 +02:00
.gitignore first commit 2026-08-10 15:59:10 +02:00
Cargo.lock first commit 2026-08-10 15:59:10 +02:00
Cargo.toml first commit 2026-08-10 15:59:10 +02:00
README.md first commit 2026-08-10 15:59:10 +02:00

type_level_str

Bounded string representation for type-level programming.

As an example, here's a type-level implementation of a set of strings:

use type_level_str::{StrValue, str_type};

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Set<A, B>(A, B);
impl<A, B> Set<A, B> {
    fn add<C>(self, c: C) -> <Self as AddElt<C>>::Output where Self: AddElt<C> {
        self.add_elt(c)
    }
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct EmptySet;
impl EmptySet {
    fn add<C>(self, c: C) -> <Self as AddElt<C>>::Output where Self: AddElt<C> {
        self.add_elt(c)
    }
}
fn compare_sets() {
    assert_eq!(
        EmptySet.add(<str_type!("Yup")>::new())
            .add(<str_type!("Nope")>::new())
            .add(<str_type!("Yup")>::new())
            .add(<str_type!("Maybe")>::new()),
        EmptySet.add(<str_type!("Maybe")>::new())
            .add(<str_type!("Maybe")>::new())
            .add(<str_type!("Nope")>::new())
            .add(<str_type!("Yup")>::new())
    )
}


trait AddElt<C> {
    type Output;
    fn add_elt(self, c: C) -> Self::Output;
}
impl<C> AddElt<C> for EmptySet {
    type Output = Set<C, Self>;
    fn add_elt(self, c: C) -> Self::Output {
        Set(c, self)
    }
}
impl<C, D, R: AddElt<C>> AddElt<C> for (Set<D, R>, type_level_str::Less) {
    type Output = Set<C, Set<D, R>>;
    fn add_elt(self, c: C) -> Self::Output {
        Set(c, self.0)
    }
}
impl<C, D, R: AddElt<C>> AddElt<C> for (Set<D, R>, type_level_str::Equal) {
    type Output = Set<D, R>;
    fn add_elt(self, _: C) -> Self::Output {
        self.0
    }
}
impl<C, D, R: AddElt<C>> AddElt<C> for (Set<D, R>, type_level_str::Greater) {
    type Output = Set<D, <R as AddElt<C>>::Output>;
    fn add_elt(self, c: C) -> Self::Output {
        Set(self.0.0, self.0.1.add_elt(c))
    }
}
impl<C: type_level_str::CmpTo<D>, D, R> AddElt<C> for Set<D, R>
    where (Self, type_level_str::Order<C, D>): AddElt<C>
{
    type Output = <(Self, type_level_str::Order<C, D>) as AddElt<C>>::Output;
    fn add_elt(self, c: C) -> Self::Output {
        (self, type_level_str::order_type::<C, D>()).add_elt(c)
    }
}