1use rust_decimal::Decimal;
4use serde::{Deserialize, Serialize};
5
6use crate::data::Timeframe;
7use crate::int_width::IntWidth;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10pub enum InterpolationMode {
11 Braces,
12 Dollar,
13 Hash,
14}
15
16impl InterpolationMode {
17 pub fn prefix(self) -> &'static str {
18 match self {
19 InterpolationMode::Braces => "f",
20 InterpolationMode::Dollar => "f$",
21 InterpolationMode::Hash => "f#",
22 }
23 }
24
25 pub fn sigil(self) -> Option<char> {
26 match self {
27 InterpolationMode::Braces => None,
28 InterpolationMode::Dollar => Some('$'),
29 InterpolationMode::Hash => Some('#'),
30 }
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
35pub enum Literal {
36 Int(i64),
37 UInt(u64),
39 TypedInt(i64, IntWidth),
41 Number(f64),
42 Decimal(Decimal),
44 String(String),
45 Char(char),
47 FormattedString {
49 value: String,
50 mode: InterpolationMode,
51 },
52 ContentString {
54 value: String,
55 mode: InterpolationMode,
56 },
57 Bool(bool),
58 None,
60 Unit,
62 Timeframe(Timeframe),
63}
64
65impl std::fmt::Display for Literal {
66 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 Literal::Int(i) => write!(f, "{}", i),
69 Literal::UInt(u) => write!(f, "{}u64", u),
70 Literal::TypedInt(v, w) => write!(f, "{}{}", v, w),
71 Literal::Number(n) => {
72 if n.fract() == 0.0 {
73 write!(f, "{}", *n as i64)
74 } else {
75 write!(f, "{}", n)
76 }
77 }
78 Literal::Decimal(d) => write!(f, "{}D", d),
79 Literal::String(s) => write!(f, "\"{}\"", s),
80 Literal::Char(c) => write!(f, "'{}'", c.escape_default()),
81 Literal::FormattedString { value, mode } => write!(f, "{}\"{}\"", mode.prefix(), value),
82 Literal::ContentString { value, mode } => {
83 let prefix = match mode {
84 InterpolationMode::Braces => "c",
85 InterpolationMode::Dollar => "c$",
86 InterpolationMode::Hash => "c#",
87 };
88 write!(f, "{}\"{}\"", prefix, value)
89 }
90 Literal::Bool(b) => write!(f, "{}", b),
91 Literal::None => write!(f, "None"),
92 Literal::Unit => write!(f, "()"),
93 Literal::Timeframe(tf) => write!(f, "{}", tf),
94 }
95 }
96}
97
98impl Literal {
99 pub fn to_json_value(&self) -> serde_json::Value {
101 match self {
102 Literal::Int(i) => serde_json::json!(*i),
103 Literal::UInt(u) => serde_json::json!(*u),
104 Literal::TypedInt(v, _) => serde_json::json!(*v),
105 Literal::Number(n) => serde_json::json!(*n),
106 Literal::Decimal(d) => serde_json::json!(d.to_string()),
107 Literal::String(s) => serde_json::json!(s),
108 Literal::Char(c) => serde_json::json!(c.to_string()),
109 Literal::FormattedString { value, .. } => serde_json::json!(value),
110 Literal::ContentString { value, .. } => serde_json::json!(value),
111 Literal::Bool(b) => serde_json::json!(*b),
112 Literal::None => serde_json::Value::Null,
113 Literal::Unit => serde_json::Value::Null,
114 Literal::Timeframe(t) => serde_json::json!(t.to_string()),
115 }
116 }
117}
118
119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
120pub struct Duration {
121 pub value: f64,
122 pub unit: DurationUnit,
123}
124
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
126pub enum DurationUnit {
127 Seconds,
128 Minutes,
129 Hours,
130 Days,
131 Weeks,
132 Months,
133 Years,
134 Samples,
135}