1use std::fmt::Display;
2
3pub use anathema_state_derive::State;
4use anathema_store::slab::Key;
5
6pub use crate::colors::{Color, FromColor};
7pub use crate::numbers::Number;
8pub use crate::states::{AnyList, AnyMap, State, StateId, States, TypeId};
9pub use crate::store::watchers::Watcher;
10pub use crate::store::{
11 Change, Changes, SubTo, Subscriber, Watched, clear_all_changes, clear_all_subs, drain_changes, drain_watchers,
12};
13pub use crate::value::{List, Map, Maybe, Nullable, PendingValue, SharedState, Type, Value, ValueRef};
14
15mod colors;
16mod numbers;
17mod states;
18mod store;
19mod value;
20
21#[allow(unused_extern_crates)]
25extern crate self as anathema;
26#[allow(unused_imports)]
27pub use crate as state;
28
29#[derive(Debug, Copy, Clone, PartialEq)]
30pub enum Path<'e> {
31 Key(&'e str),
32 Index(usize),
33}
34
35impl From<usize> for Path<'_> {
36 fn from(value: usize) -> Self {
37 Self::Index(value)
38 }
39}
40
41impl<'a> From<&'a str> for Path<'a> {
42 fn from(value: &'a str) -> Self {
43 Self::Key(value)
44 }
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
49pub struct Hex {
50 pub r: u8,
51 pub g: u8,
52 pub b: u8,
53}
54
55impl Hex {
56 pub const BLACK: Self = Self { r: 0, g: 0, b: 0 };
57 pub const BLUE: Self = Self { r: 0, g: 0, b: 255 };
58 pub const GREEN: Self = Self { r: 0, g: 255, b: 0 };
59 pub const RED: Self = Self { r: 255, g: 0, b: 0 };
60 pub const WHITE: Self = Self { r: 255, g: 255, b: 255 };
61
62 pub const fn red_f32(&self) -> f32 {
63 self.r as f32 / u8::MAX as f32
64 }
65
66 pub const fn green_f32(&self) -> f32 {
67 self.g as f32 / u8::MAX as f32
68 }
69
70 pub const fn blue_f32(&self) -> f32 {
71 self.b as f32 / u8::MAX as f32
72 }
73
74 pub fn as_u32(&self) -> u32 {
75 ((self.r as u32) << 16) | ((self.g as u32) << 8) | (self.b as u32)
76 }
77}
78
79impl Display for Hex {
80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 write!(f, "#{:x}{:x}{:x}", self.r, self.g, self.b)
82 }
83}
84
85impl From<(u8, u8, u8)> for Hex {
86 fn from((r, g, b): (u8, u8, u8)) -> Self {
87 Self { r, g, b }
88 }
89}
90
91impl From<(f32, f32, f32)> for Hex {
92 fn from((r, g, b): (f32, f32, f32)) -> Self {
93 let r = (r * u8::MAX as f32) as u8;
94 let g = (g * u8::MAX as f32) as u8;
95 let b = (b * u8::MAX as f32) as u8;
96 Self { r, g, b }
97 }
98}
99
100impl TryFrom<&str> for Hex {
101 type Error = ();
102
103 fn try_from(hex: &str) -> Result<Self, Self::Error> {
104 if hex.is_empty() || !hex.starts_with("#") {
105 return Err(());
106 }
107
108 let hex = &hex[1..];
109 match hex.len() {
110 3 => {
111 let r = u8::from_str_radix(&hex[0..1], 16).map_err(|_| ())?;
112 let r = r << 4 | r;
113 let g = u8::from_str_radix(&hex[1..2], 16).map_err(|_| ())?;
114 let g = g << 4 | g;
115 let b = u8::from_str_radix(&hex[2..3], 16).map_err(|_| ())?;
116 let b = b << 4 | b;
117 Ok(Self::from((r, g, b)))
118 }
119 6 => {
120 let r = u8::from_str_radix(&hex[0..2], 16).map_err(|_| ())?;
121 let g = u8::from_str_radix(&hex[2..4], 16).map_err(|_| ())?;
122 let b = u8::from_str_radix(&hex[4..6], 16).map_err(|_| ())?;
123 Ok(Self::from((r, g, b)))
124 }
125 _ => Err(()),
126 }
127 }
128}
129
130#[cfg(test)]
131mod test {
132 use super::*;
133
134 #[test]
135 fn from_str_for_hex() {
136 let case1 = "#aabbcc";
137 let case2 = "#abc";
138
139 let result_1 = Hex::try_from(case1).unwrap();
140 let result_2 = Hex::try_from(case2).unwrap();
141 let expected = Hex::from((0xaa, 0xbb, 0xcc));
142
143 assert_eq!(result_1, expected);
144 assert_eq!(result_2, expected);
145 }
146}