parse_book_source/analyzer/
json.rs

1use super::Analyzer;
2use crate::utils::json_path;
3use crate::Result;
4use serde_json::Value;
5
6pub struct JsonPathAnalyzer {
7    content: Value,
8}
9
10impl Analyzer for JsonPathAnalyzer {
11    fn parse(content: &str) -> crate::Result<Self>
12    where
13        Self: Sized,
14    {
15        Ok(Self {
16            content: serde_json::from_str(content)?,
17        })
18    }
19
20    fn get_string(&self, rule: &str) -> Result<String> {
21        let result = json_path(&self.content, rule)?;
22        if let Value::Array(arr) = result {
23            return value_to_string(&arr[0]);
24        }
25        value_to_string(&result)
26    }
27
28    fn get_elements(&self, rule: &str) -> Result<Vec<String>> {
29        let result = json_path(&self.content, rule)?;
30        if let Value::Array(arr) = result {
31            if arr.len() == 1 && arr[0].is_array() {
32                Ok(arr[0]
33                    .as_array()
34                    .unwrap()
35                    .iter()
36                    .map(|v| v.to_string())
37                    .collect())
38            } else {
39                Ok(arr.into_iter().map(|v| v.to_string()).collect())
40            }
41        } else {
42            Ok(vec![result.to_string()])
43        }
44    }
45}
46
47pub fn value_to_string(data: &Value) -> crate::Result<String> {
48    match data {
49        Value::String(s) => Ok(s.to_string()),
50        Value::Number(n) => Ok(n.to_string()),
51        Value::Bool(b) => Ok(b.to_string()),
52        _ => Err(anyhow::anyhow!("Invalid value type").into()),
53    }
54}