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
81
82
83
84
85
86
use crate::error::{Error, Result};
use crate::model::data_entry::DataEntry::{
    BinaryEntry, BooleanEntry, DeleteEntry, IntegerEntry, StringEntry,
};
use crate::util::{Base64, JsonDeserializer};
use serde_json::Value;

#[derive(Clone, Eq, PartialEq, Debug)]
pub enum DataEntry {
    IntegerEntry { key: String, value: i64 },
    BooleanEntry { key: String, value: bool },
    BinaryEntry { key: String, value: Vec<u8> },
    StringEntry { key: String, value: String },
    DeleteEntry { key: String },
}

impl DataEntry {
    pub fn key(&self) -> String {
        match self {
            IntegerEntry { key, .. } => key.clone(),
            BooleanEntry { key, .. } => key.clone(),
            BinaryEntry { key, .. } => key.clone(),
            StringEntry { key, .. } => key.clone(),
            DeleteEntry { key, .. } => key.clone(),
        }
    }
}

impl TryFrom<&Value> for DataEntry {
    type Error = Error;

    fn try_from(value: &Value) -> Result<Self> {
        let key_field = JsonDeserializer::safe_to_string_from_field(value, "key")?;
        let value_field = &value["value"];
        let entry_type = value["type"].as_str();
        match entry_type {
            Some(data_entry_type) => match data_entry_type {
                "binary" => Ok(BinaryEntry {
                    key: key_field,
                    value: Base64::decode(&JsonDeserializer::safe_to_string(value_field)?)?,
                }),
                "boolean" => Ok(BooleanEntry {
                    key: key_field,
                    value: JsonDeserializer::safe_to_boolean(value_field)?,
                }),
                "integer" => Ok(IntegerEntry {
                    key: key_field,
                    value: JsonDeserializer::safe_to_int(value_field)?,
                }),
                "string" => Ok(StringEntry {
                    key: key_field,
                    value: JsonDeserializer::safe_to_string(value_field)?,
                }),
                _ => Err(Error::JsonParseError {
                    field: data_entry_type.to_owned(),
                    json: value.to_string(),
                }),
            },
            None => Ok(DeleteEntry { key: key_field }),
        }
        // let string_data_entry_type = JsonDeserializer::safe_to_string_from_field(value, "type")?;
        // let data_entry_type = string_data_entry_type.as_str();
        // match data_entry_type {
        //     "binary" => Ok(BinaryEntry {
        //         key: key_field,
        //         value: Base64::decode(&JsonDeserializer::safe_to_string(value_field)?)?,
        //     }),
        //     "boolean" => Ok(BooleanEntry {
        //         key: key_field,
        //         value: JsonDeserializer::safe_to_boolean(value_field)?,
        //     }),
        //     "integer" => Ok(IntegerEntry {
        //         key: key_field,
        //         value: JsonDeserializer::safe_to_int(value_field)?,
        //     }),
        //     "string" => Ok(StringEntry {
        //         key: key_field,
        //         value: JsonDeserializer::safe_to_string(value_field)?,
        //     }),
        //     _ => Err(Error::JsonParseError {
        //         field: data_entry_type.to_owned(),
        //         json: value.to_string(),
        //     }),
        // }
    }
}