routee_compass/plugin/input/default/inject/
write_mode.rs

1use crate::plugin::input::InputPluginError;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Debug, Serialize, Deserialize, Clone)]
6#[serde(rename_all = "snake_case")]
7pub enum WriteMode {
8    Overwrite,
9    Append,
10    FailIfExisting,
11    Ignore,
12}
13
14impl WriteMode {
15    /// write a key/value pair to an existing query using this [`WriteMode`].
16    pub fn write_to_query(
17        &self,
18        query: &mut serde_json::Value,
19        key: &str,
20        value: &Value,
21    ) -> Result<(), InputPluginError> {
22        match self {
23            WriteMode::Overwrite => {
24                query[key] = value.clone();
25                Ok(())
26            }
27            WriteMode::Append => match query.get_mut(key) {
28                Some(existing) => match (existing, value) {
29                    (Value::Array(a), Value::Array(b)) => {
30                        a.append(&mut b.clone());
31                        Ok(())
32                    }
33                    (Value::Object(a), Value::Object(b)) => {
34                        for (k, v) in b.iter() {
35                            a.insert(k.to_string(), v.clone());
36                        }
37                        Ok(())
38                    }
39                    (a, b) => Err(InputPluginError::InputPluginFailed(format!(
40                        "while injecting value to key '{}' on append mode, found that types mismatch ({} != {})",
41                        key,
42                        json_type(a),
43                        json_type(b)
44                    ))),
45                },
46                None => {
47                    query[key] = value.clone();
48                    Ok(())
49                }
50            },
51            WriteMode::FailIfExisting => {
52                match query.get(key) {
53                    Some(existing) => {
54                        let msg = format!("while injecting value '{}' with fail_if_existing mode, found key already exists with value: {}", 
55                            key,
56                            serde_json::to_string(existing).unwrap_or_default()
57                        );
58                        Err(InputPluginError::InputPluginFailed(msg))
59                    },
60                    None => {
61                        Self::Overwrite.write_to_query(query, key, value)
62                    },
63                }
64            },
65            WriteMode::Ignore => {
66                match query.get(key) {
67                    Some(_) => {
68                        Ok(())
69                    },
70                    None => {
71                        Self::Overwrite.write_to_query(query, key, value)
72                    },
73                }
74            },
75        }
76    }
77}
78
79fn json_type(a: &Value) -> String {
80    match a {
81        Value::Null => String::from("Null"),
82        Value::Bool(_) => String::from("Bool"),
83        Value::Number(_) => String::from("Number"),
84        Value::String(_) => String::from("String"),
85        Value::Array(_) => String::from("Array"),
86        Value::Object(_) => String::from("Object"),
87    }
88}