use std::fmt;
use std::ops::{Deref, DerefMut};
use serde::de::Visitor;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Subcomponent(pub er7::Subcomponent);
impl From<er7::Subcomponent> for Subcomponent {
fn from(inner: er7::Subcomponent) -> Subcomponent {
Subcomponent(inner)
}
}
impl From<Subcomponent> for er7::Subcomponent {
fn from(outer: Subcomponent) -> er7::Subcomponent {
outer.0
}
}
impl Deref for Subcomponent {
type Target = er7::Subcomponent;
fn deref(&self) -> &er7::Subcomponent {
&self.0
}
}
impl DerefMut for Subcomponent {
fn deref_mut(&mut self) -> &mut er7::Subcomponent {
&mut self.0
}
}
impl Serialize for Subcomponent {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.0.raw)
}
}
struct SubcomponentVisitor;
impl Visitor<'_> for SubcomponentVisitor {
type Value = Subcomponent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string holding one ER7 subcomponent, escape sequences as sent")
}
fn visit_str<E>(self, value: &str) -> Result<Subcomponent, E>
where
E: serde::de::Error,
{
Ok(Subcomponent(er7::Subcomponent::new(value)))
}
}
impl<'de> Deserialize<'de> for Subcomponent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(SubcomponentVisitor)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn serializes_as_a_bare_string() {
let leaf = Subcomponent(er7::Subcomponent::new("SMITH"));
assert_eq!(serde_json::to_string(&leaf).unwrap(), r#""SMITH""#);
}
#[test]
fn round_trips_the_explicit_null() {
let null = Subcomponent(er7::Subcomponent::new(er7::message::NULL));
let json = serde_json::to_string(&null).unwrap();
let back: Subcomponent = serde_json::from_str(&json).unwrap();
assert!(back.is_null());
}
#[test]
fn round_trips_an_empty_subcomponent() {
let empty = Subcomponent::default();
let json = serde_json::to_string(&empty).unwrap();
let back: Subcomponent = serde_json::from_str(&json).unwrap();
assert!(back.is_empty());
assert!(!back.is_null());
}
#[test]
fn deref_reaches_the_inner_api() {
let separators = er7::Separators::default();
let leaf = Subcomponent(er7::Subcomponent::new(r"a\T\b"));
assert_eq!(leaf.value(&separators), "a&b");
}
}