custom_types/
custom_types.rs1use lineic::LinearInterpolator;
4
5fn main() {
6 let interpolator: LinearInterpolator<1, u8, NumericUnicode> =
9 LinearInterpolator::new(0..=26, &[['a'.into()], ['z'.into()]]);
10
11 let result = interpolator.interpolate(17);
14 println!(
15 "The 17th letter of the alphabet is: {:?}",
16 NumericUnicode::to_string(&result)
17 );
18}
19
20#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
23struct NumericUnicode(u32);
24impl NumericUnicode {
25 fn to_string(values: &[Self]) -> String {
27 values.iter().map(|v| char::from(*v)).collect()
28 }
29}
30impl From<char> for NumericUnicode {
31 fn from(value: char) -> NumericUnicode {
32 NumericUnicode(value as u32)
33 }
34}
35impl From<NumericUnicode> for char {
36 fn from(value: NumericUnicode) -> char {
37 if let Some(c) = std::char::from_u32(value.0) {
39 c
40 } else {
41 let mut distance = 1;
43 loop {
44 let below = value.0.checked_sub(distance);
45 if let Some(c) = below.and_then(std::char::from_u32) {
46 break c;
47 }
48
49 let above = value.0.checked_add(distance);
50 if let Some(c) = above.and_then(std::char::from_u32) {
51 break c;
52 }
53
54 distance += 1;
55 }
56 }
57 }
58}
59
60impl std::fmt::Display for NumericUnicode {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 write!(f, "{}", char::from(*self))
63 }
64}
65
66impl lineic::Numeric for NumericUnicode {
68 const MAX: Self = NumericUnicode(u32::MAX);
70 const ZERO: Self = NumericUnicode(0);
71 const ONE: Self = NumericUnicode(1);
72
73 fn abs(self) -> Self {
75 self
76 }
77
78 fn clamp(self, min: Self, max: Self) -> Self {
81 Self(if min > max {
82 std::cmp::Ord::clamp(self.0, min.0, max.0)
83 } else {
84 std::cmp::Ord::clamp(self.0, max.0, min.0)
85 })
86 }
87
88 fn from_usize(value: usize) -> Option<Self> {
93 u32::try_from(value).ok().map(Self)
94 }
95
96 fn into_f64(self) -> f64 {
97 self.0 as f64
98 }
99
100 fn from_f64(value: f64) -> Option<Self> {
101 if value < u32::MAX as f64 && value >= 0.0 {
102 Some(Self(value as u32))
103 } else {
104 None
105 }
106 }
107
108 fn checked_sub(self, other: Self) -> Option<Self> {
113 self.0.checked_sub(other.0).map(Self)
114 }
115
116 fn checked_add(self, other: Self) -> Option<Self> {
117 self.0.checked_add(other.0).map(Self)
118 }
119
120 fn checked_mul(self, other: Self) -> Option<Self> {
121 self.0.checked_mul(other.0).map(Self)
122 }
123
124 fn checked_div(self, other: Self) -> Option<Self> {
125 self.0.checked_div(other.0).map(Self)
126 }
127}