Macro tstr::TS

source ·
macro_rules! TS {
    ($($expr:expr),* $(,)* ) => { ... };
}
Expand description

The type of a type-level string, always a TStr.

§Arguments

You can use any of these as arguments:

  • String literals (eg: TS!("hello"), TS!(r#"world"#))

  • Integers (eg: TS!(0), TS!(100)): converting the integer to decimal, then stringifying it.

  • Single identifiers (eg: TS!(foo), TS!(bar)): stringifying the identifier.

  • A comma separated list of the other valid arguments to this macro (eg: TS!(foo, "bar", 0)), this evaluates to a tuple of TStrs.

  • concat!(...)-like syntax: concatenates its arguments, accepting the same arguments as this macro.

  • stringify!(...)-like syntax: stringifies its arguments.

§Examples

§ToVariant

This example demonstrates how you can use type-level strings to create a GetVariant trait which gets the data in a variant if the enum is that variant.

use tstr::TS;

fn main(){
    let foo = Enum::Foo(3, 5);
    let bar = Enum::Bar("hello".to_string());
     
    assert_eq!(foo.to_variant(Foo::NEW), Some((3, 5)));
    assert_eq!(foo.to_variant(Bar::NEW), None);
     
    assert_eq!(bar.to_variant(Foo::NEW), None);
    assert_eq!(bar.to_variant(Bar::NEW), Some("hello".to_string()));
}

type Foo = TS!(Foo);

type Bar = TS!(Bar);

trait ToVariant<V> {
    type Output;
     
    fn to_variant(&self, variant: V) -> Option<Self::Output>;
}

enum Enum {
    Foo(u32, u64),
    Bar(String),
}

impl ToVariant<TS!(Foo)> for Enum {
    type Output = (u32, u64);
     
    fn to_variant(&self, variant: TS!(Foo)) -> Option<Self::Output> {
        match self {
            Self::Foo(l, r) => Some((*l, *r)),
            _ => None,
        }
    }
}

impl ToVariant<TS!(Bar)> for Enum {
    type Output = String;
     
    fn to_variant(&self, variant: TS!(Bar)) -> Option<Self::Output> {
        match self {
            Self::Bar(s) => Some(s.clone()),
            _ => None,
        }
    }
}

§Equivalences

This example demonstrates which invocations of TS produce the same type.

use tstr::TS;

type Hello1 = TS!("hello");
type Hello2 = TS!(hello); // This is equivalent to `TS!("hello")`

type HundredA = TS!("100");
type HundredB = TS!(100);   // equivalent to `TS!("100")`
type HundredC = TS!(0x64);  // equivalent to `TS!("100")`
type HundredD = TS!(0b1100100);  // equivalent to `TS!("100")`

type Tup = TS!(foo, 1, "bar"); // equivalent to `(TS!(foo), TS!(1), TS!(bar))`

// Equivalent to TS!("foo4bar200")
type Conc = TS!(concat!(foo, 0b100, "bar", 200));