1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
mod base16;
mod color;

use serde::{Deserialize, Serialize};
use std::{fmt, str::FromStr};

pub use crate::scheme::base16::Base16Scheme;
pub use crate::scheme::color::Color;
use crate::TintedBuilderError;

/// Enum representing schemes for different scheme systems. This enum is non-exhaustive, meaning
/// additional variants may be added in future versions without it being considered a breaking
/// change.
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum Scheme {
    /// Base16 variant with Base16Scheme deserialized content.
    Base16(Base16Scheme),
    /// Base24 variant with Base16Scheme deserialized content. Base16Scheme is built to support
    /// basic supersets of Base16 schemes.
    Base24(Base16Scheme),
}

impl Scheme {
    pub fn get_scheme_system(&self) -> SchemeSystem {
        match self {
            Scheme::Base16(_) => SchemeSystem::Base16,
            Scheme::Base24(_) => SchemeSystem::Base24,
        }
    }
}

/// Enum representing the scheme system. This enum is non-exhaustive, meaning additional variants
/// may be added in future versions without it being considered a breaking change.
#[non_exhaustive]
#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SchemeSystem {
    /// Base16 scheme system, the default.
    #[default]
    Base16,
    /// Base24 scheme system.
    Base24,
}

impl SchemeSystem {
    /// Returns the string representation of the `SchemeSystem`.
    pub fn as_str(&self) -> &str {
        match self {
            SchemeSystem::Base16 => "base16",
            SchemeSystem::Base24 => "base24",
        }
    }
}

impl fmt::Display for SchemeSystem {
    /// Formats the `SchemeSystem` for display purposes.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.as_str())?;
        Ok(())
    }
}

impl FromStr for SchemeSystem {
    type Err = TintedBuilderError;

    /// Parses a string to create a `SchemeSystem`.
    ///
    /// # Errors
    ///
    /// Returns a `TintedBuilderError` if the input string does not match
    /// any valid scheme variant.
    fn from_str(system_str: &str) -> Result<Self, Self::Err> {
        match system_str {
            "base16" => Ok(Self::Base16),
            "base24" => Ok(Self::Base24),
            _ => Err(TintedBuilderError::InvalidSchemeSystem(
                system_str.to_string(),
            )),
        }
    }
}

/// Enum representing variants of a color scheme, such as Dark or Light. This enum is
/// non-exhaustive, meaning additional variants may be added in future versions without it being
/// considered a breaking change.
#[non_exhaustive]
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SchemeVariant {
    /// Dark variant of the color scheme, the default.
    #[default]
    Dark,
    /// Light variant of the color scheme.
    Light,
}

impl FromStr for SchemeVariant {
    type Err = TintedBuilderError;

    /// Parses a string to create a `SchemeVariant`.
    ///
    /// # Errors
    ///
    /// Returns a `TintedBuilderError` if the input string does not match
    /// any valid scheme variant.
    fn from_str(variant_str: &str) -> Result<Self, Self::Err> {
        match variant_str {
            "light" => Ok(Self::Light),
            "dark" => Ok(Self::Dark),
            _ => Err(TintedBuilderError::InvalidSchemeVariant(
                variant_str.to_string(),
            )),
        }
    }
}

impl SchemeVariant {
    /// Returns the string representation of the `SchemeVariant`.
    pub fn as_str(&self) -> &str {
        match self {
            SchemeVariant::Dark => "dark",
            SchemeVariant::Light => "light",
        }
    }
}

impl fmt::Display for SchemeVariant {
    /// Formats the `SchemeVariant` for display purposes.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.as_str())?;
        Ok(())
    }
}