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
118
119
120
121
122
123
124
125
126
127
128
//! This module defines a trait `UpCastAs<T>` which allows one to upcast (as in only types which make sense
//! and can fit it another are allowed) between primitive types. These follow a simple hierarchy:
//!
//! ```
//! f64 > f32 > u64 > u32 > u16 > u8
//! f64 > f32 > i64 > i32 > i16 > i8
//! ```
//!
//! Signed and unsigned types don't mix well. You can see these as implication rules, as in a type
//! which is `UpCastAs<u64>` implies it can be cast from `u32` since `u64 > u32`. And in this
//! scheme, `UpCastAs<f64>` means it can be cast from a `f64`, which would mean it can be up cast
//! from any number type.
//!
//! # Examples
//!
//! Examples of `cast`:
//!
//! ```
//! fn example<T: UpCastAs<u32>>() {
//! let _: T = cast(10u8);
//! let _ = cast::<u8, T>(10u8); // Alternate syntax, uglier.
//! let _: T = cast(10u16);
//! let _: T = cast(10u32);
//! let _: T = cast(10u64); // Error, u64 > u32
//! let _: T = cast(10f32); // Error, f32 > u32
//! let _: T = cast(10f64); // Error, f32 > u32
//! }
//! ```
//!
//! `cast` is just a thin wrapper around `UpCastAs::from`:
//!
//! ```
//! fn example<T: UpCastAs<u32>>() {
//! let _: T = UpCastAs::from(10u8);
//! let _: T = UpCastAs::from(10u16);
//! // ...
//! }
//! ```
//!
//! You can also call from directly from `T`, *but it will not follow the implication rules*, it'll
//! only recognize casting from `V` if `T: UpCastAs<V>`, so this is *not recommended*:
//!
//! ```
//! fn example<T: UpCastAs<u32>>() {
//! let _ = T::from(10u16); // Error
//! let _ = T::from(10u32);
//! let _ = T::from(10u64); // Error.
//! }
//! ```
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
// cast_rule!(u8 as u16);
// cast_rule!(u8 as u32);
// cast_rule!(u8 as u64);
// cast_rule!(u8 as f32);
// cast_rule!(u8 as f64);
// Implications. Pyramid.
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;
cast_rule!;