1use chrono::{DateTime, Utc};
2use std::{
3 collections::HashMap,
4 str::{Chars, FromStr},
5};
6use uuid::Uuid;
7
8struct JsonDecoder;
9impl JsonDecoder {
10 fn derive_key(enumerator: &mut Chars) -> String {
11 let mut current_key = String::new();
12 while let Some(key_content) = enumerator.next() {
13 if key_content != '"' {
14 current_key.push(key_content)
15 } else {
16 for t in enumerator.by_ref() {
18 if t == ':' {
19 break;
20 }
21 }
22 break;
23 }
24 }
25 current_key
26 }
27
28 fn derive_value<T: Iterator<Item = char>>(enumerator: &mut T) -> String {
29 let mut value_start = ' ';
30 while value_start == ' ' || value_start == ',' {
31 if let Some(v) = enumerator.next() {
32 value_start = v;
33 } else {
34 return String::new();
35 }
36 }
37 let exec = match value_start {
38 '\"' => JsonTypeString::extract,
39 '{' => JsonTypeObject::extract,
40 '[' => JsonTypeArray::extract,
41 _ => JsonTypePrimitive::extract,
42 };
43 exec(enumerator, value_start.to_string())
44 }
45}
46
47#[derive(Debug)]
54pub struct JsonObject {
55 keys: HashMap<String, String>,
56}
57
58impl JsonObject {
59 pub fn empty() -> JsonObject {
63 JsonObject {
64 keys: HashMap::new(),
65 }
66 }
67
68 pub fn from_string(json: &str) -> JsonObject {
75 let mut keys: HashMap<String, String> = HashMap::new();
76 let mut enumerator = json.chars();
77 while let Some(c) = enumerator.next() {
78 if c == '"' {
79 let (k, v) = (
80 JsonDecoder::derive_key(&mut enumerator),
81 JsonDecoder::derive_value(&mut enumerator),
82 );
83 keys.insert(k, v);
84 }
85 }
86 JsonObject { keys }
88 }
89
90 pub fn get<T: JsonRetrieve>(&self, key: &str) -> Result<T, JsonParseError> {
97 T::parse(key.to_string(), self.keys.get(key))
98 }
99
100 pub fn set<T: ToJson>(&mut self, key: &str, data: T) {
107 self.keys.insert(key.to_string(), data.to_json());
108 }
109}
110impl Default for JsonObject {
111 fn default() -> Self {
112 JsonObject::empty()
113 }
114}
115
116#[derive(Debug)]
117pub struct JsonArray {
118 values: Vec<String>,
119}
120impl JsonArray {
121 pub fn empty() -> JsonArray {
125 JsonArray { values: Vec::new() }
126 }
127
128 pub fn from_string(json: &str) -> JsonArray {
136 let mut values: Vec<String> = Vec::new();
137 let mut enumerator = json.chars().peekable();
138
139 while let Some(v) = enumerator.peek() {
140 if v.is_whitespace() || *v == '[' {
141 enumerator.next();
142 } else {
143 break;
144 }
145 }
146 while enumerator.peek().is_some() {
147 if *enumerator.peek().unwrap_or(&'_') == ']' {
148 _ = enumerator.next();
149 continue;
150 }
151 let v = JsonDecoder::derive_value(&mut enumerator);
152 values.push(v);
153 }
154 JsonArray { values }
155 }
156
157 pub fn get<T: JsonRetrieve>(&self, index: usize) -> Result<T, JsonParseError> {
164 T::parse(index.to_string(), self.values.get(index))
165 }
166
167 pub fn map<T: JsonRetrieve>(&self) -> Result<Vec<T>, JsonParseError> {
171 if self.values.is_empty() {
172 return Ok(Vec::new());
173 }
174 let mut build = Vec::new();
175 for i in 0..self.values.len() {
176 let value = self.values.get(i);
177 build.push(T::parse(i.to_string(), value)?);
178 }
179 Ok(build)
180 }
181
182 pub fn map_drop<T: JsonRetrieve>(&self) -> Vec<T> {
186 if self.values.is_empty() {
187 return Vec::new();
188 }
189 let mut build = Vec::new();
190 for i in 0..self.values.len() {
191 let value = &self.values[i];
192 if let Ok(val) = T::parse(i.to_string(), Some(value)) {
193 build.push(val);
194 }
195 }
196 build
197 }
198}
199impl Default for JsonArray {
200 fn default() -> Self {
201 JsonArray::empty()
202 }
203}
204
205trait JsonType {
206 fn extract<T: Iterator<Item = char>>(stream: &mut T, intl_value: String) -> String;
207}
208
209struct JsonTypePrimitive;
210impl JsonType for JsonTypePrimitive {
211 fn extract<T: Iterator<Item = char>>(stream: &mut T, intl_value: String) -> String {
212 let mut buf = intl_value;
213 for n in stream.by_ref() {
214 if n.is_whitespace() || n == ',' || n == '}' || n == ']' {
215 break;
216 }
217 buf.push(n);
218 }
219 buf
220 }
221}
222
223struct JsonTypeString;
224impl JsonType for JsonTypeString {
225 fn extract<T: Iterator<Item = char>>(stream: &mut T, intl_value: String) -> String {
226 let mut buf = intl_value;
227 let mut prev = '_';
228 let mut prev_prev = '_';
229 for n in stream.by_ref() {
230 buf.push(n);
231 if n == '"' && (prev != '\\' || prev_prev == '\\') {
232 break;
233 }
234 prev_prev = prev;
235 prev = n;
236 }
237 buf
238 }
239}
240
241struct JsonTypeObject;
242impl JsonType for JsonTypeObject {
243 fn extract<T: Iterator<Item = char>>(stream: &mut T, intl_value: String) -> String {
244 let mut buf = intl_value;
245 let mut sep_stack = 1;
246
247 let mut prev = '_';
248 let mut prev_prev = '_';
249 let mut is_in_string = false;
250
251 for n in stream.by_ref() {
252 if n == '"' && (prev != '\\' || prev_prev == '\\') {
253 is_in_string = !is_in_string;
254 }
255 if !is_in_string && n.is_whitespace() {
256 continue;
257 }
258 buf.push(n);
259 if n == '{' {
260 sep_stack += 1
261 } else if n == '}' {
262 sep_stack -= 1
263 }
264 if sep_stack == 0 {
265 break;
266 }
267 prev_prev = prev;
268 prev = n;
269 }
270 buf
271 }
272}
273
274struct JsonTypeArray;
275impl JsonType for JsonTypeArray {
276 fn extract<T: Iterator<Item = char>>(stream: &mut T, intl_value: String) -> String {
277 let mut buf = intl_value;
278 let mut sep_stack = 1;
279
280 let mut prev = '_';
281 let mut prev_prev = '_';
282 let mut is_in_string = false;
283
284 for n in stream.by_ref() {
285 if n == '"' && (prev != '\\' || prev_prev == '\\') {
286 is_in_string = !is_in_string;
287 }
288 if !is_in_string && n.is_whitespace() {
289 continue;
290 }
291 buf.push(n);
292 if n == '[' {
293 sep_stack += 1
294 } else if n == ']' {
295 sep_stack -= 1
296 }
297 if sep_stack == 0 {
298 break;
299 }
300 prev_prev = prev;
301 prev = n;
302 }
303 buf
304 }
305}
306
307#[derive(Debug)]
308pub enum JsonParseError {
309 NotFound(String),
310 InvalidType(String, &'static str),
311}
312
313pub trait ToJson {
319 fn to_json(&self) -> String;
322}
323
324pub trait FromJson {
330 fn from_json(json: &JsonObject) -> Result<Self, JsonParseError>
331 where
332 Self: Sized;
333}
334
335impl ToJson for String {
336 fn to_json(&self) -> String {
337 let mut o = String::new();
338 o += "\"";
339 o += &self
340 .replace('\\', "\\\\")
341 .replace('"', "\\\"")
342 .replace('\n', "\\n")
343 .replace('\t', "\\t");
344 o += "\"";
345 o
346 }
347}
348impl ToJson for str {
349 fn to_json(&self) -> String {
350 let mut o = String::new();
351 o += "\"";
352 o += &self
353 .replace('\\', "\\\\")
354 .replace('"', "\\\"")
355 .replace('\n', "\\n")
356 .replace('\t', "\\t");
357 o += "\"";
358 o
359 }
360}
361impl ToJson for i32 {
362 fn to_json(&self) -> String {
363 self.to_string()
364 }
365}
366impl ToJson for i64 {
367 fn to_json(&self) -> String {
368 self.to_string()
369 }
370}
371impl ToJson for u32 {
372 fn to_json(&self) -> String {
373 self.to_string()
374 }
375}
376impl ToJson for u64 {
377 fn to_json(&self) -> String {
378 self.to_string()
379 }
380}
381impl ToJson for f32 {
382 fn to_json(&self) -> String {
383 self.to_string()
384 }
385}
386impl ToJson for f64 {
387 fn to_json(&self) -> String {
388 self.to_string()
389 }
390}
391impl ToJson for bool {
392 fn to_json(&self) -> String {
393 if *self {
394 "true".to_string()
395 } else {
396 "false".to_string()
397 }
398 }
399}
400impl<T: ToJson> ToJson for Vec<T> {
401 fn to_json(&self) -> String {
402 let mut output = String::new();
403 output += "[";
404 for i in self.iter() {
405 output += &i.to_json();
406 output += ",";
407 }
408 if !self.is_empty() {
409 output.pop();
410 }
411 output += "]";
412 output
413 }
414}
415impl<T: ToJson> ToJson for Option<T> {
416 fn to_json(&self) -> String {
417 match self {
418 Some(x) => x.to_json(),
419 None => "null".to_string(),
420 }
421 }
422}
423impl<K: ToJson, V: ToJson> ToJson for HashMap<K, V> {
424 fn to_json(&self) -> String {
425 let mut output = String::new();
426 output += "{";
427 for (k, v) in self {
428 output += "\"";
429 output += &k.to_json();
430 output += "\":";
431 output += &v.to_json();
432 output += ",";
433 }
434 output.pop();
435 output += "}";
436 output
437 }
438}
439impl ToJson for JsonObject {
440 fn to_json(&self) -> String {
441 let mut output = "{".to_string();
442 for (k, v) in &self.keys {
443 output += "\"";
444 output += k;
445 output += "\":";
446 output += v;
447 output += ",";
448 }
449 if output != "{" {
450 output.pop();
451 }
452 output += "}";
453 output
454 }
455}
456impl ToJson for JsonArray {
457 fn to_json(&self) -> String {
458 let mut output = "[".to_string();
459 for v in &self.values {
460 output += v;
461 output += ",";
462 }
463 output.pop();
464 output += "]";
465 output
466 }
467}
468
469pub trait JsonRetrieve {
470 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError>
471 where
472 Self: Sized;
473}
474
475impl JsonRetrieve for String {
476 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
477 let val = value.ok_or(JsonParseError::NotFound(key.clone()))?;
478 if val.len() < 2 {
479 return Err(JsonParseError::InvalidType(key, "String"));
480 }
481 Ok(val[1..val.len() - 1].replace("\\\"", "\"").to_string())
482 }
483}
484impl JsonRetrieve for i32 {
485 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
486 if let Some(v) = value {
487 Ok(v.parse()
488 .map_err(|_| JsonParseError::InvalidType(key, "i32"))?)
489 } else {
490 Err(JsonParseError::NotFound(key))
491 }
492 }
493}
494impl JsonRetrieve for i64 {
495 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
496 if let Some(v) = value {
497 Ok(v.parse()
498 .map_err(|_| JsonParseError::InvalidType(key, "i64"))?)
499 } else {
500 Err(JsonParseError::NotFound(key))
501 }
502 }
503}
504impl JsonRetrieve for f32 {
505 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
506 if let Some(v) = value {
507 Ok(v.parse()
508 .map_err(|_| JsonParseError::InvalidType(key, "f32"))?)
509 } else {
510 Err(JsonParseError::NotFound(key))
511 }
512 }
513}
514impl JsonRetrieve for f64 {
515 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
516 if let Some(v) = value {
517 Ok(v.parse()
518 .map_err(|_| JsonParseError::InvalidType(key, "f64"))?)
519 } else {
520 Err(JsonParseError::NotFound(key))
521 }
522 }
523}
524impl JsonRetrieve for bool {
525 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
526 if let Some(v) = value {
527 match v.as_ref() {
528 "true" => Ok(true),
529 "false" => Ok(false),
530 _ => Err(JsonParseError::InvalidType(key, "bool")),
531 }
532 } else {
533 Err(JsonParseError::NotFound(key))
534 }
535 }
536}
537impl<T: JsonRetrieve> JsonRetrieve for Vec<T> {
538 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
539 JsonArray::from_string(value.ok_or(JsonParseError::NotFound(key))?).map()
540 }
541}
542impl<T: JsonRetrieve> JsonRetrieve for Option<T> {
543 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
544 if let Some(v) = value {
545 if v != "null" {
546 return Ok(Some(T::parse(key, value)?));
547 }
548 }
549 Ok(None)
550 }
551}
552impl JsonRetrieve for JsonObject {
553 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
554 Ok(JsonObject::from_string(
555 value.ok_or(JsonParseError::NotFound(key))?,
556 ))
557 }
558}
559impl JsonRetrieve for JsonArray {
560 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
561 Ok(JsonArray::from_string(
562 value.ok_or(JsonParseError::NotFound(key))?,
563 ))
564 }
565}
566impl<T: FromJson> JsonRetrieve for T {
567 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
568 Self::from_json(&JsonObject::from_string(
569 value.ok_or(JsonParseError::NotFound(key))?,
570 ))
571 }
572}
573
574impl JsonRetrieve for Uuid {
575 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
576 let val = value.ok_or_else(|| JsonParseError::NotFound(key.clone()))?;
577 let string_val = val[1..val.len() - 1].replace("\\\"", "\"").to_string();
578 Uuid::from_str(&string_val).map_err(|_| JsonParseError::InvalidType(key, "UUID"))
579 }
580}
581impl ToJson for Uuid {
582 fn to_json(&self) -> String {
583 format!("\"{}\"", self)
584 }
585}
586
587impl JsonRetrieve for DateTime<Utc> {
588 fn parse(key: String, value: Option<&String>) -> Result<Self, JsonParseError> {
589 if let Some(v) = value {
590 Ok(DateTime::parse_from_rfc3339(&v.replace('\"', ""))
591 .map_err(|_| JsonParseError::InvalidType(key, "RFC3339 Date"))?
592 .with_timezone(&Utc))
593 } else {
594 Err(JsonParseError::NotFound(key))
595 }
596 }
597}
598
599impl ToJson for DateTime<Utc> {
600 fn to_json(&self) -> String {
601 format!("\"{}\"", self.to_rfc3339())
602 }
603}