1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
#![no_std] /*! This crate allows for the creation of type-level values. Any value can be type-level as long as it can be initialized as a constant. All type-level values implement the TypeVal trait, and so can be provided as type parameters. ## Example ```rust #[macro_use] extern crate type_val; use type_val::TypeVal; use std::marker::PhantomData; fn main() { let mut adder = Adder::<Two, One>::new(); assert_eq!(adder.sum, 2); adder.add(); assert_eq!(adder.sum, 3); } def_type_val! { type One: u32 = 1; type Two: u32 = 2; } struct Adder<S, I> { sum: u32, _marker: PhantomData<(S, I)>, } impl <S, I> Adder<S, I> where S: TypeVal<u32>, I: TypeVal<u32>, { fn new() -> Adder<S, I> { Adder { // Get the value of S sum: S::VAL, _marker: PhantomData, } } fn add(&mut self) { // Get the value of I self.sum += I::VAL; } } ``` !*/ /// A trait implemented by type-level values. pub trait TypeVal<T> { /// The value held. const VAL: T; } /** This macro is used to implement the TypeVal trait. Any number of values can be initialized with a single invocation. Items prefixed by `pub` are public. Attributes to be applied to items in a block, including doc comments, should go above their targets. ## Example ```rust def_type_val! { type One: i32 = 1; #[derive(Clone, Copy)] type True: bool = true; /// Negative one pub type NegOne: i32 = -1; pub type False: bool = false; } println!("One = {}, True = {}, NegOne = {}, False = {}", One::VAL, True::VAL, NegOne::VAL, False::VAL); ``` **/ #[macro_export] macro_rules! def_type_val { {$(#[$attr:meta])* type $name:ident: $type:ty = $value:expr; $($next:tt)*} => { $(#[$attr])* struct $name; impl $crate::TypeVal<$type> for $name { const VAL: $type = $value; } def_type_val!($($next)*); }; {$(#[$attr:meta])* pub type $name:ident: $type:ty = $value:expr; $($next:tt)*} => { $(#[$attr])* pub struct $name; impl $crate::TypeVal<$type> for $name { const VAL: $type = $value; } def_type_val!($($next)*); }; () => {}; }