Skip to main content

rust_web_server/json/property/
mod.rs

1//! One JSON property: [`JSONProperty`] (name and type) and [`JSONValue`] (the
2//! parsed value — string, bool, object, array, `i128`, `f64` or null).
3
4use crate::json::{JSON_TYPE};
5use std::fmt::{Display, Formatter};
6use crate::core::New;
7use crate::null::Null;
8use crate::symbol::SYMBOL;
9
10#[cfg(test)]
11mod tests;
12
13pub struct JSONProperty {
14    pub property_name: String,
15    pub property_type: String,
16}
17
18pub struct JSONValue {
19    pub f64: Option<f64>,
20    pub i128: Option<i128>,
21    pub string: Option<String>,
22    pub object: Option<String>,
23    pub array: Option<String>,
24    pub bool: Option<bool>,
25    pub null: Option<Null>,
26}
27
28impl New for JSONValue {
29    fn new() -> JSONValue {
30        JSONValue {
31            f64: None,
32            i128: None,
33            string: None,
34            object: None,
35            array: None,
36            bool: None,
37            null: None,
38        }
39    }
40}
41
42impl JSONValue {
43    pub fn float_number_with_precision(&self, number_of_digits: u8) -> String {
44        let number = self.f64.as_ref().unwrap();
45        let formatted = format!("{0:.1$}", number, number_of_digits as usize);
46        formatted.to_string()
47    }
48}
49
50impl Display for JSONValue {
51    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
52        if self.f64.is_some() {
53            let f64 = self.f64.unwrap();
54            let formatted : String = format!("{:.13}", f64);
55            return f.write_str(formatted.as_str());
56        }
57
58        if self.i128.is_some() {
59            let formatted = self.i128.unwrap().to_string();
60            return f.write_str(formatted.as_str());
61        }
62
63        if self.string.is_some() {
64            let formatted = self.string.as_ref().unwrap();
65            return f.write_str(formatted.as_str());
66        }
67
68        if self.array.is_some() {
69            let formatted = self.array.as_ref().unwrap();
70            return f.write_str(formatted.as_str());
71        }
72
73        if self.null.is_some() {
74            return f.write_str("null");
75        }
76
77        if self.object.is_some() {
78            let formatted = self.object.as_ref().unwrap();
79            return f.write_str(formatted.as_str());
80        }
81
82        if self.bool.is_some() {
83            let formatted = self.bool.as_ref().unwrap();
84            return f.write_str(formatted.to_string().as_str());
85        }
86
87        f.write_str("Something Went Wrong. There is no value for any type.")
88
89    }
90}
91
92impl JSONProperty {
93    pub fn parse(raw_string: &str) -> Result<(JSONProperty, JSONValue), String> {
94        let mut property = JSONProperty { property_name: "".to_string(), property_type: "".to_string() };
95        let mut value = JSONValue {
96            f64: None,
97            i128: None,
98            string: None,
99            object: None,
100            array: None,
101            bool: None,
102            null: None,
103        };
104
105        let boxed_split = raw_string.trim().split_once(SYMBOL.colon);
106        if boxed_split.is_none() {
107            let message = format!("Not a valid string as a key-value: {}", raw_string);
108            return Err(message);
109        }
110
111        let (mut _key, mut _value) = boxed_split.unwrap();
112        _key = _key.trim();
113        _value = _value.trim();
114
115        let is_null = _value == "null";
116        let is_string = _value.starts_with(SYMBOL.quotation_mark) && _value.ends_with(SYMBOL.quotation_mark);
117        let is_array = _value.starts_with(SYMBOL.opening_square_bracket) && _value.ends_with(SYMBOL.closing_square_bracket);
118        let is_object = _value.starts_with(SYMBOL.opening_curly_bracket) && _value.ends_with(SYMBOL.closing_curly_bracket);
119        let is_boolean = (_value == "true") || (_value == "false");
120        let is_number = !is_string && !is_null && !is_array && !is_object && !is_boolean;
121
122        if !is_null && !is_string && !is_array && !is_object && !is_number && !is_boolean {
123            let message = format!("Is not valid key value pair: {} {}", _key, _value);
124            return Err(message);
125        }
126
127
128
129        if is_null {
130            property.property_type = JSON_TYPE.string.to_string();
131            property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
132            value.null = Some(Null{});
133
134        }
135
136        if is_string {
137            property.property_type = JSON_TYPE.string.to_string();
138            property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
139            value.string = Some(_value.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string());
140        }
141
142        if is_number {
143            let boxed_i128_parse = _value.parse::<i128>();
144            if boxed_i128_parse.is_err() {
145                let boxed_f64_parse = _value.parse::<f64>();
146                if boxed_f64_parse.is_err() {
147                    let message = format!("unable to parse number: {}: {}", _key, _value);
148                    return Err(message);
149                } else {
150                    property.property_type = JSON_TYPE.number.to_string();
151                    property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
152                    let f64 = boxed_f64_parse.unwrap();
153                    value.f64 = Some(f64);
154                }
155            } else {
156                property.property_type = JSON_TYPE.integer.to_string();
157                property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
158                let i128 = boxed_i128_parse.unwrap();
159                value.i128 = Some(i128);
160            }
161        }
162
163        if is_array {
164            property.property_type = JSON_TYPE.array.to_string();
165            property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
166            value.array = Some(_value.to_string());
167        }
168
169        if is_object {
170            property.property_type = JSON_TYPE.object.to_string();
171            property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
172            value.object = Some(_value.to_string());
173        }
174
175        if is_boolean {
176            let is_true = _value == "true";
177            property.property_type = JSON_TYPE.boolean.to_string();
178            property.property_name = _key.replace(SYMBOL.quotation_mark, SYMBOL.empty_string).to_string();
179            value.bool = Some(is_true);
180        }
181
182        Ok((property, value))
183    }
184}
185
186
187