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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
use crate::prelude::*;
use regex::Regex;
/// An enum representing the JSON output format mode.
pub enum JsonMode {
/// Outputs the JSON in an indented format.
Indented,
/// Outputs the JSON in an inline format.
Inline,
}
impl Value {
/// Converts a `Value` into a JSON string.
///
/// # Arguments
///
/// * `mode` - A `JsonMode` value representing the JSON output format mode.
///
/// # Examples
///
/// ```no_run
/// use json_utils::{Value, JsonMode};
///
/// let value = Value::payload_to_value("{\"name\":\"John Doe\",\"age\":30,\"is_active\":true}").unwrap();
/// let json_string = value.to_json(JsonMode::Indented);
/// println!("{}", json_string);
/// ```
pub fn to_json(&self, mode: JsonMode) -> String {
let value = Value::to_json_inner(self, 0);
match mode {
JsonMode::Inline => Self::inline(value),
JsonMode::Indented => value,
}
}
/// Converts the inline JSON string into an indented JSON string.
fn inline(value: String) -> String {
let re = Regex::new(r"(\n)|(\t)").unwrap();
let result = re.replace_all(&value, "");
result.to_string()
}
/// Generates tab indentation.
fn tabs(total: i32) -> String {
vec!["\t"; total as usize].join("")
}
/// Converts a `Value` into a JSON string.
fn to_json_inner(val: &Value, children: i32) -> String {
match val {
Value::Object(o) => {
let contents: Vec<_> = o
.iter()
.map(|(name, value)| {
format!(
"\n\t{}\"{}\": {}",
&Self::tabs(children),
name,
Value::to_json_inner(value, children + 1)
)
})
.collect();
format!("{{{}\n{}}}", contents.join(","), &Self::tabs(children))
}
Value::Array(a) => {
let contents: Vec<_> = a
.into_iter()
.map(|value| Value::to_json_inner(value, children + 1))
.collect();
format!(
"[\n\t{}{}\n{}]",
&Self::tabs(children),
contents.join(&format!(",\n\t{}", &Self::tabs(children))),
&Self::tabs(children)
)
}
Value::String(s) => {
let string = s.as_str();
let re = Regex::new(r#"""#).unwrap();
let list = string
.chars()
.into_iter()
.map(|c| c.to_string())
.collect::<Vec<_>>();
let mut result = list.clone();
let mut add_posi = 0;
for item in re.captures_iter(string) {
let range = item.get(0).unwrap().range();
if range.start.eq(&0) {
result.insert(range.start + add_posi, r#"\"#.to_string());
add_posi += 1;
} else {
let before = range.start - 1;
if list.get(before).unwrap().ne(r#"\"#) {
result.insert(range.start + add_posi, r#"\"#.to_string());
add_posi += 1;
}
}
}
format!("\"{}\"", result.join(""))
}
Value::Number(n) => format!("{}", n),
Value::Boolean(b) => format!("{}", b),
Value::Null => "null".to_string(),
Value::Undefined => "undefined".to_string(),
Value::DateTime(date_time) => format!("\"{}\"", date_time),
}
}
}