Skip to content

Commit

Permalink
Serialize and deserialize detail as JSON string
Browse files Browse the repository at this point in the history
  • Loading branch information
petkovicdanilo committed Sep 8, 2021
1 parent 9d75783 commit fa9f59a
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion src/distribution/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,53 @@ pub struct ErrorInfo {
/// MAY be empty.
message: Option<String>,

#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(default, skip_serializing_if = "Option::is_none", with = "json_string")]
#[builder(default = "None")]
/// The detail field is OPTIONAL and MAY contain arbitrary JSON data providing information
/// the client can use to resolve the issue.
detail: Option<String>,
}

mod json_string {
use std::str::FromStr;

use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::Error;

let opt = Option::<serde_json::Value>::deserialize(deserializer)?;

if let Some(data) = opt {
let data = serde_json::to_string(&data).map_err(Error::custom)?;
return Ok(Some(data));
}

Ok(None)
}

pub fn serialize<S>(target: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::Error;

match target {
Some(data) => {
if let Ok(json_value) = serde_json::Value::from_str(data) {
json_value.serialize(serializer)
} else {
Err(Error::custom("invalid JSON"))
}
}
_ => unreachable!(),
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit fa9f59a

Please sign in to comment.