Macro core_extensions::quasiconst [−][src]
const_val
only.Declare types that emulate generic constants.
Syntax
For an example using all the syntax, you can look at the All of the syntax section
Generated code
This macro generates:
-
A generic zero-sized struct with the name and generic parameters of the
const
definition passed to this macro. -
An impl of the
ConstVal
trait for the struct, with the value for the constant . -
An inherent
VAL
associated constant for the struct, to avoid requiring thatConstVal
is imported to writeFoo::VAL
. -
An inherent
NEW
associated constant that constructs the struct.
Version compatibility
This macro can only be used inside of functions since Rust 1.45.0, before that version it can only be used outside of functions.
This is because it uses a dependency-free procedural macro to do some token munging.
Examples
Basic
use core_extensions::{getconst, quasiconst}; quasiconst!{ const NONE[T]: Option<T> = None } // `getconst` is the unambiguous way to get the constant assert_eq!([getconst!(NONE<String>); 4], [None, None, None, None]); // The `VAL` associated constant is another way to get the constant. // // I get worse compiler errors with `::VAL` than with `getconst` // when the bounds of the generic constant aren't satisfied. assert_eq!([NONE::<u8>::VAL; 4], [None, None, None, None]);
ConstVal
This example shows that you can use the generic constants with the ConstVal
trait
use core_extensions::{ConstDefault, ConstVal, quasiconst}; quasiconst!{ pub const PAIR[T: ConstDefault]: (T, T) = ConstDefault::DEFAULT; } fn constant<U: ConstVal>() -> U::Ty { U::VAL } /// You can pass the type you want `constrained` to return as the first type argument. fn constrained<T, U: ConstVal<Ty = T>>() -> T { U::VAL } assert_eq!(constant::<PAIR<[u8; 3]>>(), ([0, 0, 0], [0, 0, 0])); assert_eq!(constant::<PAIR<bool>>(), (false, false)); // Pair<_> is inferred to be `Pair<u8>` assert_eq!(constrained::<(u8, u8), PAIR<_>>(), (0, 0)); // Pair<_> is inferred to be `Pair<String>` assert_eq!(constrained::<(String, String), PAIR<_>>(), (String::new(), String::new()));
All of the syntax
Note: This macro allows const parameters (and doesn’t require enabling the “rust_1_51” feature to use them).
use core_extensions::{ConstDefault, getconst, quasiconst}; assert_eq!(getconst!(REFD<'static>), ""); assert_eq!(getconst!(REFD<'static, str>), ""); assert_eq!(getconst!(REFD<'static, [u8]>), &[]); assert_eq!(getconst!(CONST_GEN<2>), [1, 3]); assert_eq!(getconst!(CONST_GEN<4>), [1, 3, 6, 10]); assert_eq!(getconst!(CONST_GEN<6>), [1, 3, 6, 10, 15, 21]); quasiconst!{ /// You can document and use attributes on the generated `REFD` struct. pub(crate) const REFD['a: 'a, T: 'a + ?Sized = str]: &'a T where[&'a T: ConstDefault] = <&'a T>::DEFAULT; // The macro parses defaulted const parameters, but they're not supported by Rust yet. pub const CONST_GEN[const N: usize]: [u128; N] = { let mut array = [1u128; N]; let mut i = 1; while i < array.len() { array[i] += array[i - 1] + i as u128; i += 1; } array }; }