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
//! Type related utilities. use super::std_reexports::*; // ================ // === Anything === // ================ /// Placeholder type used to represent any value type. It is useful to define type-level relations /// like defining an unit with any quantity, let it be distance or mass. #[derive(Clone,Copy,Debug,PartialEq)] pub struct Anything {} // =================== // === TypeDisplay === // =================== /// Like `Display` trait but for types. However, unlike `Display` it defaults to /// `impl::any::type_name` if not provided with explicit implementation. pub trait TypeDisplay { fn type_display() -> String; } impl<T> TypeDisplay for T { default fn type_display() -> String { type_name::<Self>().to_string() } } /// Formats the type for the user-facing output. pub fn type_display<T:TypeDisplay>() -> String { <T as TypeDisplay>::type_display() } // ============= // === Value === // ============= /// Defines relation between types and values, like between `True` and `true`. pub trait KnownTypeValue { /// The value-level counterpart of this type-value. type Value; /// The value of this type-value. fn value() -> Self::Value; } pub type TypeValue<T> = <T as KnownTypeValue>::Value; // ======================= // === Type-level Bool === // ======================= /// Type level `true` value. #[derive(Clone,Copy,Debug)] pub struct True {} /// Type level `false` value. #[derive(Clone,Copy,Debug)] pub struct False {} impl KnownTypeValue for True { type Value = bool; fn value() -> Self::Value { true } } impl KnownTypeValue for False { type Value = bool; fn value() -> Self::Value { false } } // ======================== // === Type Conversions === // ======================== /// This is used to make type inference better at use sites - without it, /// Rust would force one to write the `where` clause at every use site. pub trait IntoSelfFrom<T> = Sized where T:Into<Self>; /// Can be transformed from and into. pub trait BiInto<T> = Sized + Into<T> + IntoSelfFrom<T>;