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
|
use core::fmt;
use std::str::FromStr;
use anyhow::{Result, bail};
use diesel::{backend::Backend, deserialize::{self, FromSql, FromSqlRow}, expression::AsExpression, serialize::{self, ToSql}, sql_types::Text, sqlite::Sqlite};
use serde::{Deserialize, Serialize};
#[derive(
Eq,
PartialEq,
Serialize,
Deserialize,
Clone,
Debug,
AsExpression,
FromSqlRow,
)]
#[diesel(sql_type=Text)]
pub enum BudgetPeriodUnit {
Day,
Month,
Year,
}
impl fmt::Display for BudgetPeriodUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BudgetPeriodUnit::Day => "DAY".fmt(f),
BudgetPeriodUnit::Month => "MONTH".fmt(f),
BudgetPeriodUnit::Year => "YEAR".fmt(f),
}
}
}
impl FromStr for BudgetPeriodUnit {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"DAY" => Ok(BudgetPeriodUnit::Day),
"MONTH" => Ok(BudgetPeriodUnit::Month),
"YEAR" => Ok(BudgetPeriodUnit::Year),
_ => bail!("\"{}\" is not a valid budget period unit. Valid values are: DAY, MONTH, YEAR", s),
}
}
}
impl ToSql<Text, Sqlite> for BudgetPeriodUnit {
fn to_sql<'b>(
&'b self,
out: &mut diesel::serialize::Output<'b, '_, Sqlite>,
) -> serialize::Result {
out.set_value(self.to_string());
Ok(serialize::IsNull::No)
}
}
impl FromSql<Text, Sqlite> for BudgetPeriodUnit {
fn from_sql(bytes: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<BudgetPeriodUnit> {
let str = <String as FromSql<Text, Sqlite>>::from_sql(bytes)?;
Ok(str.parse()?)
}
}
#[cfg(test)]
mod test {
use anyhow::Result;
use super::BudgetPeriodUnit;
#[test]
fn display_when_day_then_day() {
assert_eq!("DAY", format!("{}", BudgetPeriodUnit::Day));
}
#[test]
fn display_when_month_then_month() {
assert_eq!("MONTH", format!("{}", BudgetPeriodUnit::Month));
}
#[test]
fn display_when_year_then_year() {
assert_eq!("YEAR", format!("{}", BudgetPeriodUnit::Year));
}
#[test]
fn from_str_when_day_then_day() {
let result: Result<BudgetPeriodUnit> = "DAY".parse();
assert!(result.is_ok());
assert_eq!(BudgetPeriodUnit::Day, result.unwrap());
}
#[test]
fn from_str_when_month_then_month() {
let result: Result<BudgetPeriodUnit> = "MONTH".parse();
assert!(result.is_ok());
assert_eq!(BudgetPeriodUnit::Month, result.unwrap());
}
#[test]
fn from_str_when_year_then_year() {
let result: Result<BudgetPeriodUnit> = "YEAR".parse();
assert!(result.is_ok());
assert_eq!(BudgetPeriodUnit::Year, result.unwrap());
}
#[test]
fn from_str_when_sentence_case_day_then_err() {
let result: Result<BudgetPeriodUnit> = "Day".parse();
assert!(result.is_err());
}
}
|