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>;