use super::*; use core::fmt::Debug; // XXX: Don't trace these functions as they are used in the transfer of API logs, which will recurse! // #[instrument(level = "trace", ret, err)] pub fn deserialize_json<'a, T: de::Deserialize<'a> + Debug>( arg: &'a str, ) -> Result { serde_json::from_str(arg).map_err(|e| VeilidAPIError::ParseError { message: e.to_string(), value: format!( "deserialize_json:\n---\n{}\n---\n to type {}", arg, std::any::type_name::() ), }) } // #[instrument(level = "trace", ret, err)] pub fn deserialize_opt_json( arg: Option, ) -> Result { let arg = arg.as_ref().ok_or_else(|| VeilidAPIError::ParseError { message: "invalid null string".to_owned(), value: format!( "deserialize_json_opt: null to type {}", std::any::type_name::() ), })?; deserialize_json(arg) } // #[instrument(level = "trace", ret)] pub fn serialize_json(val: T) -> String { match serde_json::to_string(&val) { Ok(v) => v, Err(e) => { panic!("failed to serialize json value: {}\nval={:?}", e, val); } } } pub mod json_as_string { use std::fmt::Display; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &T, serializer: S) -> Result where T: Display, S: Serializer, { serializer.collect_str(value) } pub fn deserialize<'de, T, D>(deserializer: D) -> Result where T: FromStr, T::Err: Display, D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } pub mod opt_json_as_string { use std::fmt::Display; use std::str::FromStr; use serde::{de, Deserialize, Deserializer, Serializer}; pub fn serialize(value: &Option, serializer: S) -> Result where T: Display, S: Serializer, { match value { Some(v) => serializer.collect_str(v), None => serializer.serialize_none(), } } pub fn deserialize<'de, T, D>(deserializer: D) -> Result, D::Error> where T: FromStr, T::Err: Display, D: Deserializer<'de>, { match Option::::deserialize(deserializer)? { None => Ok(None), Some(v) => Ok(Some(v.parse::().map_err(de::Error::custom)?)), } } }