rust_tvtf_api/
arg.rs

1use serde::{Deserialize, Serialize};
2
3pub type Args = Vec<Arg>;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(tag = "type", content = "value")]
7#[serde(rename_all = "lowercase")]
8pub enum Arg {
9    Int(i64),
10    String(String),
11    Bool(bool),
12    Float(f64),
13    Timestamp(i64),
14    Interval(String),
15    Column(String),
16}
17
18impl From<&str> for Arg {
19    fn from(value: &str) -> Self {
20        Arg::String(value.to_string())
21    }
22}
23
24impl From<String> for Arg {
25    fn from(value: String) -> Self {
26        Arg::String(value)
27    }
28}
29
30impl From<bool> for Arg {
31    fn from(value: bool) -> Self {
32        Arg::Bool(value)
33    }
34}
35
36impl From<f64> for Arg {
37    fn from(value: f64) -> Self {
38        Arg::Float(value)
39    }
40}
41
42impl From<i64> for Arg {
43    fn from(value: i64) -> Self {
44        Arg::Int(value)
45    }
46}
47
48// for deserialize only
49#[derive(Debug, Clone, Deserialize)]
50pub(crate) struct NamedArg {
51    pub name: String,
52    #[serde(flatten)]
53    pub arg: Arg,
54}
55
56#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
57#[serde(rename_all = "UPPERCASE")]
58pub enum ArgType {
59    Int,
60    String,
61    Bool,
62    Float,
63    Timestamp,
64    Interval,
65    Column,
66}
67
68impl Arg {
69    pub fn is_scalar(&self) -> bool {
70        use Arg as T;
71        matches!(
72            self,
73            T::Int(_) | T::String(_) | T::Bool(_) | T::Float(_) | T::Timestamp(_) | T::Interval(_)
74        )
75    }
76
77    pub fn is_column(&self) -> bool {
78        use Arg as T;
79        matches!(self, T::Column(_))
80    }
81}
82
83#[cfg(test)]
84mod tests {
85
86    use anyhow::Context;
87    use serde_json::json;
88
89    use super::*;
90
91    #[test]
92    fn parse_args() -> anyhow::Result<()> {
93        serde_json::from_value::<Args>(
94                    json! {[{"type":"column","value":"test_cte"},{"type":"string","value":"output_test_name"}]},
95                ).context("Failed to parse arguments")?;
96        Ok(())
97    }
98
99    #[test]
100    fn parse_named_args() -> anyhow::Result<()> {
101        serde_json::from_value::<Vec<NamedArg>>(
102                    json! {[{"name":"asdf","type":"column","value":"test_cte"},{"name":"foo","type":"string","value":"output_test_name"}]},
103                ).context("Failed to parse arguments")?;
104        Ok(())
105    }
106}