1use super::*;
6use serde_derive::Serialize;
7
8#[derive(Debug, Clone, Serialize)]
9pub enum Conversion {
10 None,
11 Expr(Expr),
12 Degree(Degree),
13 List(Vec<String>),
14 Offset(i64),
15 #[serde(skip)]
16 Timezone(Tz),
17}
18
19#[derive(Debug, Clone, Serialize)]
20#[serde(rename_all = "camelCase")]
21#[serde(tag = "type", content = "value")]
22pub enum Query {
23 Expr(Expr),
24 Convert(Expr, Conversion, Option<u8>, Digits),
25 Factorize(Expr),
26 UnitsFor(Expr),
27 Search(String),
28 Error(String),
29}
30
31impl fmt::Display for Conversion {
32 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match *self {
34 Conversion::None => write!(fmt, "nothing"),
35 Conversion::Expr(ref expr) => write!(fmt, "{}", expr),
36 Conversion::Degree(ref deg) => write!(fmt, "{}", deg),
37 Conversion::List(ref list) => {
38 let list = list
39 .iter()
40 .map(|x| x.to_string())
41 .collect::<Vec<_>>()
42 .join(", ");
43 write!(fmt, "{}", list)
44 }
45 Conversion::Offset(off) => write!(fmt, "{:02}:{:02}", off / 3600, (off / 60) % 60),
46 Conversion::Timezone(ref tz) => write!(fmt, "{:?}", tz),
47 }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::Conversion;
54 use crate::ast::{Degree, Expr};
55 use chrono_tz::Tz;
56
57 #[test]
58 fn conversion_display() {
59 assert_eq!(Conversion::None.to_string(), "nothing");
60 assert_eq!(
61 Conversion::Expr(Expr::new_unit("a".to_owned())).to_string(),
62 "a"
63 );
64 assert_eq!(Conversion::Degree(Degree::Celsius).to_string(), "°C");
65 assert_eq!(
66 Conversion::List(vec!["a".to_owned(), "b".to_owned()]).to_string(),
67 "a, b"
68 );
69 assert_eq!(Conversion::Offset(3600 * 7).to_string(), "07:00");
70 assert_eq!(
71 Conversion::Timezone(Tz::US__Pacific).to_string(),
72 "US/Pacific"
73 );
74 }
75}