use crate::app_system_error;
use crate::serde::de::DeserializeOwned;
use crate::serde::Serialize;
use crate::serde_json::value::RawValue;
use crate::serde_json::Value;
use crate::tina::data::AppResult;
use tracing::Level;
pub struct JsonUtil;
impl JsonUtil {
pub fn to_json_value<T>(obj: &T) -> Value
where
T: Serialize,
{
match serde_json::to_value(obj) {
Ok(v) => v,
Err(err) => {
if tracing::enabled!(Level::ERROR) {
tracing::error!("{}", err);
}
Value::Null
}
}
}
pub fn to_json_raw_value<T>(obj: &T) -> Box<RawValue>
where
T: Serialize,
{
match serde_json::value::to_raw_value(obj) {
Ok(v) => v,
Err(err) => {
if tracing::enabled!(Level::ERROR) {
tracing::error!("{}", err);
}
serde_json::value::to_raw_value(&Value::Null).unwrap_or_else(|err| {
tracing::error!("{}", err);
Default::default()
})
}
}
}
pub fn to_json_string<T>(obj: &T) -> String
where
T: Serialize,
{
match serde_json::to_string(obj) {
Ok(s) => s,
Err(err) => {
if tracing::enabled!(Level::ERROR) {
tracing::error!("{}", err);
}
"".to_owned()
}
}
}
pub fn to_json_string_pretty<T>(obj: &T) -> String
where
T: Serialize,
{
match serde_json::to_string_pretty(obj) {
Ok(s) => s,
Err(_) => "".to_owned(),
}
}
pub fn parse_json_string<T>(json: &str) -> AppResult<T>
where
T: Sized + DeserializeOwned,
{
serde_json::from_str(json).map_err(crate::app_error_from!())
}
pub fn parse_json_value<T>(json_value: &Value) -> AppResult<T>
where
T: Sized + DeserializeOwned,
{
T::deserialize(json_value).map_err(crate::app_error_from!())
}
pub fn parse_json_raw_value<T>(json_raw_value: &RawValue) -> AppResult<T>
where
T: Sized + DeserializeOwned,
{
serde_json::from_str(json_raw_value.get()).map_err(crate::app_error_from!())
}
pub fn merge_value(value1: Value, valu2: Value) -> AppResult<Value> {
match (value1, valu2) {
(Value::Object(mut v1), Value::Object(mut v2)) => {
v1.append(&mut v2);
Ok(Value::Object(v1))
}
(Value::Array(mut v1), Value::Array(mut v2)) => {
v1.append(&mut v2);
Ok(Value::Array(v1))
}
(v1, Value::Null) => Ok(v1),
(Value::Null, v2) => Ok(v2),
_ => Err(app_system_error!("only Object, Array and Null can be merged!")),
}
}
}
#[cfg(test)]
#[allow(unused)]
mod test {
use crate::tina::util::json::JsonUtil;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Person {
name: String,
age: u8,
phones: Vec<String>,
}
#[test]
fn test() {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let p: Person = JsonUtil::parse_json_string(data).expect("test");
println!("Please call {} at the number {}", p.name, p.phones[0]);
println!("Normal: \r\n{}", JsonUtil::to_json_string(&p));
println!("Pretty: \r\n{}", JsonUtil::to_json_string_pretty(&p));
}
#[test]
fn test_vec() {
let vec1 = vec![11, 22, 33];
println!("Normal: \r\n{}", JsonUtil::to_json_string(&vec1));
println!("Pretty: \r\n{}", JsonUtil::to_json_string_pretty(&vec1));
let vec1 = vec!["11", "22", "33"];
println!("Normal: \r\n{}", JsonUtil::to_json_string(&vec1));
println!("Pretty: \r\n{}", JsonUtil::to_json_string_pretty(&vec1));
}
#[test]
#[ignore]
fn test_memory() {
loop {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;
let p: Person = JsonUtil::parse_json_string(data).expect("test");
let string = JsonUtil::to_json_string(&p);
let string1 = JsonUtil::to_json_string_pretty(&p);
}
}
}