1#![cfg_attr(not(test), no_std)]
2#![feature(const_trait_impl)]
3#![feature(impl_trait_in_assoc_type)]
4
5extern crate sys;
6use core::ptr::NonNull;
7use core::usize;
8
9use sys::error::NullPtrError;
10use sys::ffi::LCDColor;
11use sys::ffi::LCDPattern;
12use sys::ffi::LCDSolidColor;
13
14
15#[derive(PartialEq, Clone)]
16#[cfg_attr(feature = "bindings-derive-debug", derive(Debug))]
17pub enum Color<'t> {
18 Solid(LCDSolidColor),
19 Pattern(&'t LCDPattern),
20}
21
22impl Color<'_> {
23 pub const WHITE: Self = Self::Solid(LCDSolidColor::kColorWhite);
24 pub const BLACK: Self = Self::Solid(LCDSolidColor::kColorBlack);
25 pub const CLEAR: Self = Self::Solid(LCDSolidColor::kColorClear);
26 pub const XOR: Self = Self::Solid(LCDSolidColor::kColorXOR);
27}
28
29impl<'t> From<Color<'t>> for LCDColor
30 where Self: 't,
31 LCDColor: 't
32{
33 fn from(color: Color) -> Self {
34 match color {
35 Color::Solid(color) => color as LCDColor,
36 Color::Pattern(pattern) => (pattern as *const u8) as LCDColor,
37 }
38 }
39}
40
41impl<'t> TryFrom<LCDColor> for Color<'t>
42 where LCDColor: 't,
43 Self: 't
44{
45 type Error = NullPtrError;
46
47 fn try_from(color: LCDColor) -> Result<Self, Self::Error> {
48 match color {
49 0 => Ok(Self::Solid(LCDSolidColor::BLACK)),
50 1 => Ok(Self::Solid(LCDSolidColor::WHITE)),
51 2 => Ok(Self::Solid(LCDSolidColor::CLEAR)),
52 3 => Ok(Self::Solid(<LCDSolidColor as LCDColorConst>::XOR)),
53 color => {
54 NonNull::new(color as *mut LCDPattern).ok_or(NullPtrError)
55 .map(|nn| Self::Pattern(unsafe { nn.as_ref() }))
56 },
57 }
58 }
59}
60
61impl<'t> From<&'t LCDPattern> for Color<'t> {
62 fn from(pattern: &'t LCDPattern) -> Self { Color::Pattern(pattern) }
63}
64
65
66#[deprecated = "Useless until const_trait is experimental and incomplete. Use LCDColorConst instead."]
68pub trait LCDColorExt {
69 #![allow(non_snake_case)]
70 fn White() -> Self;
71 fn Black() -> Self;
72 fn Clear() -> Self;
73 fn XOR() -> Self;
74}
75
76#[allow(deprecated)]
77impl LCDColorExt for LCDColor {
78 #![allow(non_snake_case)]
79 fn White() -> Self { LCDSolidColor::kColorWhite as Self }
80 fn Black() -> Self { LCDSolidColor::kColorBlack as Self }
81 fn Clear() -> Self { LCDSolidColor::kColorClear as Self }
82 fn XOR() -> Self { LCDSolidColor::kColorXOR as Self }
83}
84
85#[allow(deprecated)]
86impl LCDColorExt for LCDSolidColor {
87 #![allow(non_snake_case)]
88 fn White() -> Self { LCDSolidColor::kColorWhite }
89 fn Black() -> Self { LCDSolidColor::kColorBlack }
90 fn Clear() -> Self { LCDSolidColor::kColorClear }
91 fn XOR() -> Self { LCDSolidColor::kColorXOR }
92}
93
94pub trait LCDColorConst {
95 const WHITE: Self;
96 const BLACK: Self;
97 const CLEAR: Self;
98 const XOR: Self;
99}
100
101impl LCDColorConst for LCDColor {
102 const WHITE: Self = LCDSolidColor::kColorWhite as Self;
103 const BLACK: Self = LCDSolidColor::kColorBlack as Self;
104 const CLEAR: Self = LCDSolidColor::kColorClear as Self;
105 const XOR: Self = LCDSolidColor::kColorXOR as Self;
106}
107
108impl LCDColorConst for LCDSolidColor {
109 const WHITE: Self = LCDSolidColor::kColorWhite as Self;
110 const BLACK: Self = LCDSolidColor::kColorBlack as Self;
111 const CLEAR: Self = LCDSolidColor::kColorClear as Self;
112 const XOR: Self = LCDSolidColor::kColorXOR as Self;
113}
114
115
116pub trait LCDColorIs {
118 fn is_solid(&self) -> bool;
119 fn is_pattern(&self) -> bool;
120}
121
122impl LCDColorIs for LCDColor {
123 fn is_solid(&self) -> bool {
124 let color = *self as usize;
125 color >= LCDSolidColor::kColorBlack as _ && color <= LCDSolidColor::kColorXOR as _
126 }
127 fn is_pattern(&self) -> bool { !self.is_solid() }
128}
129
130
131pub trait IntoLCDColor {
133 fn into_color(self) -> LCDColor;
134}
135
136impl IntoLCDColor for LCDSolidColor {
137 fn into_color(self) -> LCDColor { self as LCDColor }
138}
139
140impl<'t> IntoLCDColor for &'t LCDPattern where LCDColor: 't {
141 #[inline(always)]
142 fn into_color(self) -> LCDColor { self as *const u8 as _ }
143}
144
145
146pub trait LCDColorFmt<'t> {
148 type Display: 't + core::fmt::Debug + core::fmt::Display;
149 fn display(&'t self) -> Self::Display;
150}
151
152impl<'t> LCDColorFmt<'t> for LCDSolidColor {
153 type Display = LCDColorDisplay<'t, Self>;
154 fn display(&self) -> LCDColorDisplay<'_, Self> { LCDColorDisplay(self) }
155}
156
157pub struct LCDColorDisplay<'t, T>(&'t T);
158
159impl core::fmt::Debug for LCDColorDisplay<'_, LCDSolidColor> {
160 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
161 f.write_str("Solid")?;
162 let name = match self.0 {
163 LCDSolidColor::kColorBlack => "Black",
164 LCDSolidColor::kColorWhite => "White",
165 LCDSolidColor::kColorClear => "Clear",
166 LCDSolidColor::kColorXOR => "XOR",
167 };
168 f.write_str(name)
169 }
170}
171
172impl core::fmt::Display for LCDColorDisplay<'_, LCDSolidColor> {
173 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
174 let ch = match self.0 {
175 LCDSolidColor::kColorBlack => 'B',
176 LCDSolidColor::kColorWhite => 'W',
177 LCDSolidColor::kColorClear => 'C',
178 LCDSolidColor::kColorXOR => 'X',
179 };
180 write!(f, "{ch}")
181 }
182}
183
184impl core::fmt::Debug for LCDColorDisplay<'_, LCDColor> {
185 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
186 match self.0 {
187 n if *n == LCDSolidColor::kColorBlack as _ => LCDSolidColor::kColorBlack.display().fmt(f),
188 n if *n == LCDSolidColor::kColorWhite as _ => LCDSolidColor::kColorWhite.display().fmt(f),
189 n if *n == LCDSolidColor::kColorClear as _ => LCDSolidColor::kColorClear.display().fmt(f),
190 n if *n == LCDSolidColor::kColorXOR as _ => LCDSolidColor::kColorXOR.display().fmt(f),
191 p => write!(f, "Pattern({:p})", *p as *const u8),
192 }
193 }
194}
195
196impl core::fmt::Display for LCDColorDisplay<'_, LCDColor> {
197 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
198 match self.0 {
199 n if *n == LCDSolidColor::kColorBlack as _ => LCDSolidColor::kColorBlack.display().fmt(f),
200 n if *n == LCDSolidColor::kColorWhite as _ => LCDSolidColor::kColorWhite.display().fmt(f),
201 n if *n == LCDSolidColor::kColorClear as _ => LCDSolidColor::kColorClear.display().fmt(f),
202 n if *n == LCDSolidColor::kColorXOR as _ => LCDSolidColor::kColorXOR.display().fmt(f),
203 _ => write!(f, "Pattern"),
204 }
205 }
206}