Use strings in type-level rust programming.
- Rust 100%
| macros | ||
| src | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
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)
}
}