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 FormattedString {
47 value: String,
48 mode: InterpolationMode,
49 },
50 ContentString {
52 value: String,
53 mode: InterpolationMode,
54 },
55 Bool(bool),
56 None,
58 Unit,
60 Timeframe(Timeframe),
61}
62
63impl std::fmt::Display for Literal {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 match self {
66 Literal::Int(i) => write!(f, "{}", i),
67 Literal::UInt(u) => write!(f, "{}u64", u),
68 Literal::TypedInt(v, w) => write!(f, "{}{}", v, w),
69 Literal::Number(n) => {
70 if n.fract() == 0.0 {
71 write!(f, "{}", *n as i64)
72 } else {
73 write!(f, "{}", n)
74 }
75 }
76 Literal::Decimal(d) => write!(f, "{}D", d),
77 Literal::String(s) => write!(f, "\"{}\"", s),
78 Literal::FormattedString { value, mode } => write!(f, "{}\"{}\"", mode.prefix(), value),
79 Literal::ContentString { value, mode } => {
80 let prefix = match mode {
81 InterpolationMode::Braces => "c",
82 InterpolationMode::Dollar => "c$",
83 InterpolationMode::Hash => "c#",
84 };
85 write!(f, "{}\"{}\"", prefix, value)
86 }
87 Literal::Bool(b) => write!(f, "{}", b),
88 Literal::None => write!(f, "None"),
89 Literal::Unit => write!(f, "()"),
90 Literal::Timeframe(tf) => write!(f, "{}", tf),
91 }
92 }
93}
94
95impl Literal {
96 pub fn to_json_value(&self) -> serde_json::Value {
98 match self {
99 Literal::Int(i) => serde_json::json!(*i),
100 Literal::UInt(u) => serde_json::json!(*u),
101 Literal::TypedInt(v, _) => serde_json::json!(*v),
102 Literal::Number(n) => serde_json::json!(*n),
103 Literal::Decimal(d) => serde_json::json!(d.to_string()),
104 Literal::String(s) => serde_json::json!(s),
105 Literal::FormattedString { value, .. } => serde_json::json!(value),
106 Literal::ContentString { value, .. } => serde_json::json!(value),
107 Literal::Bool(b) => serde_json::json!(*b),
108 Literal::None => serde_json::Value::Null,
109 Literal::Unit => serde_json::Value::Null,
110 Literal::Timeframe(t) => serde_json::json!(t.to_string()),
111 }
112 }
113}
114
115#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
116pub struct Duration {
117 pub value: f64,
118 pub unit: DurationUnit,
119}
120
121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
122pub enum DurationUnit {
123 Seconds,
124 Minutes,
125 Hours,
126 Days,
127 Weeks,
128 Months,
129 Years,
130 Samples,
131}