1use crate::output::Digits;
8use crate::types::Numeric;
9use serde_derive::Serialize;
10use std::fmt;
11
12mod def;
13mod expr;
14mod query;
15
16pub use def::{DateMatch, DatePattern, Def, DefEntry, Defs, ExprString, Property};
17pub use expr::{Expr, Precedence};
18pub use query::{Conversion, Query};
19
20#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
21#[serde(rename_all = "camelCase")]
22pub enum Degree {
23 Celsius,
24 Fahrenheit,
25 Reaumur,
26 Romer,
27 Delisle,
28 Newton,
29}
30
31#[derive(Debug, Clone, Serialize, PartialEq)]
32pub enum DateToken {
33 Literal(String),
34 Number(String, Option<String>),
35 Colon,
36 Dash,
37 Space,
38 Plus,
39 Error(String),
40}
41
42#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
43#[serde(rename_all = "camelCase")]
44pub enum BinOpType {
45 Add,
46 Sub,
47 Frac,
48 Pow,
49 Equals,
50 ShiftL,
51 ShiftR,
52 Mod,
53 And,
54 Or,
55 Xor,
56}
57
58impl BinOpType {
59 pub fn symbol(self) -> &'static str {
60 match self {
61 BinOpType::Add => " + ",
62 BinOpType::Sub => " - ",
63 BinOpType::Frac => " / ",
64 BinOpType::Pow => "^",
65 BinOpType::Equals => " = ",
66 BinOpType::ShiftL => " << ",
67 BinOpType::ShiftR => " >> ",
68 BinOpType::Mod => " mod ",
69 BinOpType::And => " and ",
70 BinOpType::Or => " or ",
71 BinOpType::Xor => " xor ",
72 }
73 }
74}
75
76#[derive(Debug, Clone, Serialize, PartialEq)]
77pub struct BinOpExpr {
78 pub op: BinOpType,
79 pub left: Box<Expr>,
80 pub right: Box<Expr>,
81}
82
83#[derive(Debug, Clone, Serialize, Copy, Eq, PartialEq)]
84#[serde(rename_all = "camelCase")]
85#[serde(untagged)]
86pub enum UnaryOpType {
87 Negative,
88 Positive,
89 Degree(Degree),
90}
91
92#[derive(Debug, Clone, Serialize, PartialEq)]
93pub struct UnaryOpExpr {
94 pub op: UnaryOpType,
95 pub expr: Box<Expr>,
96}
97
98#[derive(Debug, Clone, Copy, Serialize, PartialEq)]
99#[serde(rename_all = "camelCase")]
100pub enum Function {
101 Sqrt,
102 Exp,
103 Ln,
104 Log2,
105 Log10,
106 Sin,
107 Cos,
108 Tan,
109 Asin,
110 Acos,
111 Atan,
112 Sinh,
113 Cosh,
114 Tanh,
115 Asinh,
116 Acosh,
117 Atanh,
118 Log,
119 Hypot,
120 Atan2,
121 Fac,
122}
123
124impl Function {
125 pub fn name(&self) -> &str {
126 match *self {
127 Function::Sqrt => "sqrt",
128 Function::Exp => "exp",
129 Function::Ln => "ln",
130 Function::Log2 => "log2",
131 Function::Log10 => "log10",
132 Function::Sin => "sin",
133 Function::Cos => "cos",
134 Function::Tan => "tan",
135 Function::Asin => "asin",
136 Function::Acos => "acos",
137 Function::Atan => "atan",
138 Function::Sinh => "sinh",
139 Function::Cosh => "cosh",
140 Function::Tanh => "tanh",
141 Function::Asinh => "asinh",
142 Function::Acosh => "acosh",
143 Function::Atanh => "atanh",
144 Function::Log => "log",
145 Function::Hypot => "hypot",
146 Function::Atan2 => "atan2",
147 Function::Fac => "fac",
148 }
149 }
150
151 pub fn from_name(s: &str) -> Option<Self> {
152 let func = match s {
153 "sqrt" => Function::Sqrt,
154 "exp" => Function::Exp,
155 "ln" => Function::Ln,
156 "log2" => Function::Log2,
157 "log10" => Function::Log10,
158 "sin" => Function::Sin,
159 "cos" => Function::Cos,
160 "tan" => Function::Tan,
161 "asin" => Function::Asin,
162 "acos" => Function::Acos,
163 "atan" => Function::Atan,
164 "sinh" => Function::Sinh,
165 "cosh" => Function::Cosh,
166 "tanh" => Function::Tanh,
167 "asinh" => Function::Asinh,
168 "acosh" => Function::Acosh,
169 "atanh" => Function::Atanh,
170 "log" => Function::Log,
171 "hypot" => Function::Hypot,
172 "atan2" => Function::Atan2,
173 "fac" => Function::Fac,
174 _ => return None,
175 };
176 Some(func)
177 }
178}
179
180impl fmt::Display for Degree {
181 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
182 write!(fmt, "{}", self.as_str())
183 }
184}
185
186impl Degree {
187 pub fn as_str(&self) -> &'static str {
188 match *self {
189 Degree::Celsius => "°C",
190 Degree::Fahrenheit => "°F",
191 Degree::Newton => "°N",
192 Degree::Reaumur => "°Ré",
193 Degree::Romer => "°Rø",
194 Degree::Delisle => "°De",
195 }
196 }
197
198 pub fn name_base_scale(&self) -> (&str, &str, &str) {
199 match *self {
200 Degree::Celsius => ("C", "zerocelsius", "kelvin"),
201 Degree::Fahrenheit => ("F", "zerofahrenheit", "degrankine"),
202 Degree::Reaumur => ("Ré", "zerocelsius", "reaumur_absolute"),
203 Degree::Romer => ("Rø", "zeroromer", "romer_absolute"),
204 Degree::Delisle => ("De", "zerodelisle", "delisle_absolute"),
205 Degree::Newton => ("N", "zerocelsius", "newton_absolute"),
206 }
207 }
208}
209
210impl fmt::Display for DateToken {
211 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
212 match *self {
213 DateToken::Literal(ref l) => write!(fmt, "{}", l),
214 DateToken::Number(ref i, None) => write!(fmt, "{}", i),
215 DateToken::Number(ref i, Some(ref f)) => write!(fmt, "{}.{}", i, f),
216 DateToken::Colon => write!(fmt, ":"),
217 DateToken::Dash => write!(fmt, "-"),
218 DateToken::Space => write!(fmt, " "),
219 DateToken::Plus => write!(fmt, "+"),
220 DateToken::Error(ref e) => write!(fmt, "<{}>", e),
221 }
222 }
223}