ragit_api/
json_type.rs

1use crate::error::Error;
2use serde_json::Value;
3
4/// This enum is solely for error messages.
5#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
6pub enum JsonType {
7    Null,
8    String,
9    Number,
10    Boolean,
11    Object,
12    Array,
13
14    // for nicer error messages
15    F64,
16    F32,
17    I64,
18    U64,
19    Usize,
20}
21
22impl JsonType {
23    // NOTE: this function is used to parse input of `rag config --set`
24    // NOTE: if `self` is `JsonType::Null`, then the actual type must be `Option<T>`, but there's no
25    //       way we can guess what `T` is...
26    // TODO: I don't like its implementation. It's too Javascript-ish.
27    pub fn parse(&self, s: &str) -> Result<Value, Error> {
28        if s == "null" {
29            return Ok(Value::Null);
30        }
31
32        match self {
33            JsonType::String => Ok(Value::from(s)),
34            JsonType::Number => match s.parse::<i64>() {
35                Ok(n) => Ok(Value::from(n)),
36                _ => match s.parse::<f64>() {
37                    Ok(n) => Ok(Value::from(n)),
38                    _ => match serde_json::from_str::<Value>(s) {
39                        Ok(v) => Err(Error::JsonTypeError {
40                            expected: *self,
41                            got: (&v).into(),
42                        }),
43                        Err(e) => Err(e.into()),
44                    },
45                },
46            },
47            JsonType::Boolean => match s {
48                "true" => Ok(true.into()),
49                "false" => Ok(false.into()),
50                _ => match serde_json::from_str::<Value>(s) {
51                    Ok(v) => Err(Error::JsonTypeError {
52                        expected: *self,
53                        got: (&v).into(),
54                    }),
55                    Err(e) => Err(e.into()),
56                },
57            },
58            // the most Javascript-ish part of this function. read the comments above
59            JsonType::Null => match serde_json::from_str(s) {
60                Ok(v) => Ok(v),
61                Err(_) => Ok(Value::from(s)),
62            },
63            _ => todo!(),
64        }
65    }
66}
67
68impl From<&Value> for JsonType {
69    fn from(v: &Value) -> Self {
70        match v {
71            Value::Null => JsonType::Null,
72            Value::String(_) => JsonType::String,
73            Value::Number(_) => JsonType::Number,
74            Value::Bool(_) => JsonType::Boolean,
75            Value::Object(_) => JsonType::Object,
76            Value::Array(_) => JsonType::Array,
77        }
78    }
79}