routee_compass/plugin/input/default/inject/
write_mode.rs1use 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 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}