pub struct TStr<S>(/* private fields */);Expand description
A type-level string type, emulates a &'static str const parameter.
This type is zero-sized and has an alignment of 1.
§Examples
§Emulating named parameters
This example demonstrates how you can use TStr to emulate
functions with named parameters overloaded by the name of the parameters.
use tstr::{IsTStr, TS, TStr, ts};
use std::{collections::HashMap, hash::RandomState};
{
// equivalent to HashMap::new
let mut map = HashMap::make(args!());
assert!(map.capacity() == 0);
map.insert(0, "");;
}
{
// equivalent to HashMap::with_capacity
let mut map = HashMap::make(args!(capacity: 10));
assert!(map.capacity() >= 10);
map.insert(0, "");;
}
{
// equivalent to HashMap::with_hasher
let mut map = HashMap::make(args!(hasher: RandomState::new()));
assert!(map.capacity() == 0);
map.insert(0, "");;
}
{
// equivalent to HashMap::with_capacity_and_hasher
let mut map = HashMap::make(args!(capacity: 10, hasher: RandomState::new()));
assert!(map.capacity() >= 10);
map.insert(0, "");;
}
/// The struct that encodes a named parameter by taking two arguments:
// - a `TStr` that encodes the name at the type level
/// - the type of the argument.
///
/// The parameter list as a whole is a tuple of this struct.
#[repr(transparent)]
pub struct NamedParameter<N: IsTStr, T> {
// since TStr is zero-sized, it can be put alongside the non-zero-sized
// wrapped value in a `#[repr(transparent)]` type.
name: TStr<N::Arg>,
pub value: T,
}
impl<N, T> NamedParameter<N, T>
where
N: IsTStr
{
pub const fn new(name: N, value: T) -> Self {
Self {
// `TStr::from_gen` is needed for constructing a `TStr` from a
// generic `IsTStr` type
name: TStr::from_gen(name),
value,
}
}
}
/// Custom trait for constructors.
trait Make<Args>: Sized {
fn make(args: Args) -> Self;
}
// make constructor with no parameters
impl<K, V> Make<args_ty!()> for HashMap<K, V> {
fn make(args_pat!{}: args_ty!()) -> Self {
HashMap::new()
}
}
// make constructor with a capacity parameter
impl<K, V> Make<args_ty!(capacity: usize)> for HashMap<K, V> {
fn make(args_pat!{capacity}: args_ty!(capacity: usize)) -> Self {
HashMap::with_capacity(capacity)
}
}
// make constructor with a hasher parameter
impl<K, V, S> Make<args_ty!(hasher: S)> for HashMap<K, V, S> {
fn make(args_pat!{hasher}: args_ty!(hasher: S)) -> Self {
HashMap::with_hasher(hasher)
}
}
// make constructor with capacity and hasher parameters
impl<K, V, S> Make<args_ty!(capacity: usize, hasher: S)> for HashMap<K, V, S> {
fn make(args_pat!{capacity, hasher}: args_ty!(capacity: usize, hasher: S)) -> Self {
HashMap::with_capacity_and_hasher(capacity, hasher)
}
}
macro_rules! args {
($($name:ident: $val:expr),* $(,)?) => (
($(NamedParameter::new(ts!($name), $val),)*)
)
} use args;
macro_rules! args_ty {
($($name:ident: $field_ty:ty),* $(,)?) => (
($(NamedParameter<TS!($name), $field_ty>,)*)
)
} use args_ty;
macro_rules! args_pat {
($($name:ident),* $(,)?) => (
($( NamedParameter::<TS!($name), _> { value: $name, .. }, )*)
)
} use args_pat;
§Parsing integers
Parsing integers from TStrs, since the primitive integers all have
const fn from_str_radix functions,
parsing them doesn’t require direct support from TStr itself.
(this example requires the "const_panic" feature because it uses tstr::unwrap)
use tstr::ts;
// parses the number at compile-time!
const NUMBER: u32 = tstr::unwrap!(u32::from_str_radix(tstr::to_str(ts!(1234)), 10));
assert_eq!(NUMBER, 1234u32);§Serde
TStr implements serde::{Serialize, Deserialize} when the "serde" feature is enabled.
use tstr::{TS, ts};
assert_eq!(serde_json::from_str::<TS!(foo)>(r#""foo""#).unwrap(), ts!(foo));
// trying to deserialize a `TS!(foo)` from any value other than `"foo"` produces an error
assert!(serde_json::from_str::<TS!(foo)>(r#""bar""#).is_err());
assert_eq!(serde_json::to_string(&ts!(wtf)).unwrap(), r#""wtf""#);
assert_eq!(serde_json::to_string(&ts!("hello")).unwrap(), r#""hello""#);
assert_eq!(serde_json::to_string(&ts!(12345)).unwrap(), r#""12345""#);
Implementations§
Source§impl<S: TStrArg> TStr<S>
impl<S: TStrArg> TStr<S>
Sourcepub const fn from_gen<G>(tstr: G) -> Selfwhere
G: IsTStr<Arg = S>,
pub const fn from_gen<G>(tstr: G) -> Selfwhere
G: IsTStr<Arg = S>,
Coerces an impl IsTStr into a TStr, only necessary in generic contexts
The trait method equivalent of this const function is
IsTStr::to_tstr.
While it’s always possible to construct a TStr through its
new constructor,
this method ensures that it’s the same string as the argument.
§Example
use tstr::{IsTStr, TStr};
#[repr(transparent)]
struct Foo<T, N: IsTStr> {
val: T,
// since TStr is zero-sized, it can be put in `#[repr(transparent)]` types
// next to the wrapped non-Zero-Sized-Type.
name: TStr<N::Arg>,
}
impl<T, N: IsTStr> Foo<T, N> {
pub fn new(val: T, tstr: N) -> Self {
Self{ val, name: TStr::from_gen(tstr) }
}
}Sourcepub const fn to_gen<G>(self) -> Gwhere
G: IsTStr<Arg = S>,
pub const fn to_gen<G>(self) -> Gwhere
G: IsTStr<Arg = S>,
Coerces a TStr into an impl IsTStr, only necessary in generic contexts
While it’s always possible to construct an IsTStr through its
VAL associated constant,
this method ensures that it’s the same string as Self.
§Example
use tstr::{IsTStr, TStr};
#[repr(transparent)]
struct Foo<T, N: IsTStr> {
val: T,
// since TStr is zero-sized, it can be put in `#[repr(transparent)]` types
// next to the wrapped non-Zero-Sized-Type.
name: TStr<N::Arg>,
}
impl<T, N: IsTStr> Foo<T, N> {
const fn name(&self) -> N {
self.name.to_gen()
}
}Source§impl<S> TStr<S>
impl<S> TStr<S>
Sourcepub const fn to_panicval(&self, fmtarg: FmtArg) -> PanicVal<'static>where
S: TStrArg,
Available on crate feature const_panic only.
pub const fn to_panicval(&self, fmtarg: FmtArg) -> PanicVal<'static>where
S: TStrArg,
const_panic only.const_panic-based-formatting of TStr
Sourcepub const fn to_panicvals(&self, fmtarg: FmtArg) -> [PanicVal<'static>; 1]where
S: TStrArg,
Available on crate feature const_panic only.
pub const fn to_panicvals(&self, fmtarg: FmtArg) -> [PanicVal<'static>; 1]where
S: TStrArg,
const_panic only.const_panic-based-formatting of TStr
Trait Implementations§
Source§impl<'de, SA: TStrArg> Deserialize<'de> for TStr<SA>
Available on crate feature serde only.
impl<'de, SA: TStrArg> Deserialize<'de> for TStr<SA>
serde only.Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<S> IsTStr for TStr<S>where
S: TStrArg,
impl<S> IsTStr for TStr<S>where
S: TStrArg,
Source§impl<S> Ord for TStr<S>where
S: TStrArg,
impl<S> Ord for TStr<S>where
S: TStrArg,
Source§impl<S> PanicFmt for TStr<S>where
S: TStrArg,
Available on crate feature const_panic only.
impl<S> PanicFmt for TStr<S>where
S: TStrArg,
const_panic only.