rstmt_neo/
error.rs

1/*
2    Appellation: error <module>
3    Contrib: FL03 <jo3mccain@icloud.com>
4*/
5
6pub use res::EResult;
7/// A type alias for a [`Result`](core::result::Result) that uses the [`TriadError`](TriadError) type.
8pub type TriadResult<T = ()> = core::result::Result<T, TriadError>;
9
10use rstmt::{Note, Pitch};
11
12#[derive(
13    Clone,
14    Debug,
15    Eq,
16    Hash,
17    Ord,
18    PartialEq,
19    PartialOrd,
20    strum::AsRefStr,
21    strum::EnumIs,
22    strum::VariantNames,
23    thiserror::Error,
24)]
25#[cfg_attr(
26    feature = "serde",
27    derive(serde::Deserialize, serde::Serialize),
28    serde(rename_all = "PascalCase")
29)]
30#[repr(C)]
31#[strum(serialize_all = "PascalCase")]
32pub enum TriadError {
33    #[error("InvalidPitch: {0}")]
34    InvalidPitch(String),
35    #[error("Invalid Interval: {0}")]
36    InvalidInterval(String),
37    #[error("Invalid Triad: {0:?}")]
38    InvalidTriad(String),
39    #[error("{0}")]
40    Music(#[from] rstmt::error::MusicErr),
41    #[error("{0}")]
42    Unknown(String),
43}
44
45impl TriadError {
46    pub fn invalid_pitch(msg: impl ToString) -> Self {
47        Self::InvalidPitch(msg.to_string())
48    }
49
50    pub fn invalid_interval(msg: impl ToString) -> Self {
51        Self::InvalidInterval(msg.to_string())
52    }
53
54    pub fn invalid_triad(msg: impl ToString) -> Self {
55        Self::InvalidTriad(msg.to_string())
56    }
57
58    pub fn unknown(msg: impl Into<String>) -> Self {
59        Self::Unknown(msg.into())
60    }
61}
62
63impl From<Pitch> for TriadError {
64    fn from(err: Pitch) -> Self {
65        TriadError::InvalidPitch(err.to_string())
66    }
67}
68
69impl From<(Note, Note, Note)> for TriadError {
70    fn from((r, t, f): (Note, Note, Note)) -> Self {
71        TriadError::InvalidTriad(format!("({}, {}, {})", r, t, f))
72    }
73}
74
75mod res {
76    #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
77    #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
78    pub struct EResult<A, B = A> {
79        pub expected: A,
80        pub found: B,
81    }
82
83    impl<A, B> EResult<A, B> {
84        pub fn new(expected: A, found: B) -> Self {
85            Self { expected, found }
86        }
87    }
88
89    impl<A, B> core::fmt::Display for EResult<A, B>
90    where
91        A: core::fmt::Display,
92        B: core::fmt::Display,
93    {
94        fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
95            write!(f, "Expected: {}, Found: {}", self.expected, self.found)
96        }
97    }
98}