1use core::fmt;
4
5#[derive(Debug, Clone, PartialEq)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8pub enum Value {
9 Number(f64),
11 Text(String),
13 Bool(bool),
15}
16
17impl Value {
18 #[must_use]
20 pub fn is_truthy(&self) -> bool {
21 match self {
22 Self::Bool(v) => *v,
23 Self::Number(v) => *v != 0.0,
24 Self::Text(v) => !v.is_empty(),
25 }
26 }
27}
28
29impl fmt::Display for Value {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 Self::Number(v) => {
33 if v.fract() == 0.0 && v.abs() < 1e15 {
37 write!(f, "{v:.0}")
38 } else {
39 write!(f, "{v}")
40 }
41 }
42 Self::Text(v) => f.write_str(v),
43 Self::Bool(v) => write!(f, "{v}"),
44 }
45 }
46}
47
48impl From<f64> for Value {
49 fn from(v: f64) -> Self {
50 Self::Number(v)
51 }
52}
53
54impl From<bool> for Value {
55 fn from(v: bool) -> Self {
56 Self::Bool(v)
57 }
58}
59
60impl From<String> for Value {
61 fn from(v: String) -> Self {
62 Self::Text(v)
63 }
64}
65
66impl From<&str> for Value {
67 fn from(v: &str) -> Self {
68 Self::Text(v.to_owned())
69 }
70}
71
72#[cfg(test)]
73#[path = "types_tests.rs"]
74mod tests;