1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
6pub enum ThemeMode {
7 Light,
8 Dark,
9 System,
10}
11
12impl ThemeMode {
13 pub fn as_str(self) -> &'static str {
14 match self {
15 Self::Light => "light",
16 Self::Dark => "dark",
17 Self::System => "system",
18 }
19 }
20
21 pub fn is_explicit(self) -> bool {
22 !matches!(self, Self::System)
23 }
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
28pub struct ThemeName(String);
29
30impl ThemeName {
31 pub fn new(value: impl Into<String>) -> Self {
32 Self(value.into())
33 }
34
35 pub fn as_str(&self) -> &str {
36 &self.0
37 }
38}
39
40impl AsRef<str> for ThemeName {
41 fn as_ref(&self) -> &str {
42 self.as_str()
43 }
44}
45
46#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
48pub struct ThemeVariant(String);
49
50impl ThemeVariant {
51 pub fn new(value: impl Into<String>) -> Self {
52 Self(value.into())
53 }
54
55 pub fn as_str(&self) -> &str {
56 &self.0
57 }
58}
59
60impl AsRef<str> for ThemeVariant {
61 fn as_ref(&self) -> &str {
62 self.as_str()
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
68pub enum SemanticThemeRole {
69 Background,
70 Foreground,
71 Primary,
72 Secondary,
73 Accent,
74 Muted,
75 Success,
76 Warning,
77 Danger,
78 Info,
79}
80
81impl SemanticThemeRole {
82 pub fn as_str(self) -> &'static str {
83 match self {
84 Self::Background => "background",
85 Self::Foreground => "foreground",
86 Self::Primary => "primary",
87 Self::Secondary => "secondary",
88 Self::Accent => "accent",
89 Self::Muted => "muted",
90 Self::Success => "success",
91 Self::Warning => "warning",
92 Self::Danger => "danger",
93 Self::Info => "info",
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::{SemanticThemeRole, ThemeMode, ThemeName, ThemeVariant};
101
102 #[test]
103 fn creates_theme_identity_values() {
104 let name = ThemeName::new("Acme");
105 let variant = ThemeVariant::new("high-contrast");
106
107 assert_eq!(name.as_str(), "Acme");
108 assert_eq!(variant.as_str(), "high-contrast");
109 }
110
111 #[test]
112 fn exposes_theme_mode_and_role_labels() {
113 assert_eq!(ThemeMode::Dark.as_str(), "dark");
114 assert!(ThemeMode::Light.is_explicit());
115 assert!(!ThemeMode::System.is_explicit());
116 assert_eq!(SemanticThemeRole::Danger.as_str(), "danger");
117 }
118}