parse_book_source/
variables.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::{
    utils::{replace_all, value_to_string},
    Result,
};
use anyhow::anyhow;
use regex::Regex;
use serde_json::Value;
use std::collections::HashMap;

#[derive(Debug, Clone)]
pub struct Variables {
    pub variables: HashMap<String, String>,
    pub put_rule: Regex,
    pub get_rule: Regex,
}

impl Variables {
    pub fn new() -> Result<Self> {
        Ok(Self {
            variables: HashMap::new(),
            put_rule: Regex::new(r"@put:\{(\w+):(\$.+)\}")?,
            get_rule: Regex::new(r"@get:\{(\w+)\}")?,
        })
    }

    pub fn put(&mut self, json_rule: &str, data: &Value) -> Result<String> {
        replace_all(&self.put_rule, json_rule, |capture| {
            let key = capture.get(1).ok_or(anyhow!("key is not found"))?.as_str();
            let path = capture
                .get(2)
                .ok_or(anyhow!("json path is not found"))?
                .as_str();
            let v = value_to_string(data, path)?;
            self.variables.insert(key.to_string(), v);
            Ok("".into())
        })
    }

    pub fn get(&self, json_rule: &str) -> Result<String> {
        replace_all(&self.get_rule, json_rule, |capture| {
            let key = capture.get(1).ok_or(anyhow!("key is not found"))?.as_str();
            let v = self
                .variables
                .get(key)
                .ok_or(anyhow!("key {} is not found", key))?;

            Ok(v.to_string())
        })
    }

    pub fn insert<T: ToString>(&mut self, key: &str, value: T) {
        self.variables.insert(key.to_string(), value.to_string());
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use serde_json::json;

    #[test]
    fn test_variables() -> Result<()> {
        let mut variables = Variables::new()?;
        let data = json!({
            "book":{
                "id":"123"
            }
        });
        let rule = "hello world @put:{book:$.book.id}";
        let res = variables.put(rule, &data)?;

        assert_eq!(res, "hello world ");
        assert_eq!(variables.variables.get("book"), Some(&"123".to_string()));

        let rule = "hello world @get:{book}";
        let res = variables.get(rule)?;
        assert_eq!(res, "hello world 123");
        Ok(())
    }
}