1#![deny(clippy::pedantic)]
2
3use std::fmt;
4
5use serde::{Deserialize, Deserializer, Serialize};
6
7pub(crate) mod api;
8pub mod cache;
9pub mod conditions;
10pub mod config;
11pub mod icons;
12pub mod location;
13mod weather;
14
15pub use cache::Cache;
16pub use conditions::Conditions;
17pub use config::Config;
18
19#[derive(Clone, Copy, Debug, Default, Serialize)]
20pub enum Unit {
21 C,
22 #[default]
23 F,
24}
25
26impl Unit {
27 #[must_use]
28 pub fn from_char(unit: char) -> Option<Self> {
29 match unit {
30 'c' => Some(Self::C),
31 'f' => Some(Self::F),
32 _ => None,
33 }
34 }
35
36 #[must_use]
37 pub fn as_char(&self) -> char {
38 match self {
39 Unit::C => 'c',
40 Unit::F => 'f',
41 }
42 }
43}
44
45impl fmt::Display for Unit {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 let text = match self {
48 Unit::C => "celsius",
49 Unit::F => "fahrenheit",
50 };
51 write!(f, "{text}")
52 }
53}
54
55impl<'de> Deserialize<'de> for Unit {
56 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
57 where
58 D: Deserializer<'de>,
59 {
60 let s = String::deserialize(deserializer)?.to_lowercase();
61 match s.as_str() {
62 "c" => Ok(Unit::C),
63 _ => Ok(Unit::F),
64 }
65 }
66}