1use std::fmt;
4
5use serde::de::{self, Visitor};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
39pub struct Terminator(pub er7::Terminator);
40
41impl From<er7::Terminator> for Terminator {
42 fn from(inner: er7::Terminator) -> Terminator {
43 Terminator(inner)
44 }
45}
46
47impl From<Terminator> for er7::Terminator {
48 fn from(outer: Terminator) -> er7::Terminator {
49 outer.0
50 }
51}
52
53impl Serialize for Terminator {
54 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55 where
56 S: Serializer,
57 {
58 let name = match self.0 {
59 er7::Terminator::Cr => "Cr",
60 er7::Terminator::Lf => "Lf",
61 er7::Terminator::CrLf => "CrLf",
62 };
63 serializer.serialize_str(name)
64 }
65}
66
67struct TerminatorVisitor;
68
69impl Visitor<'_> for TerminatorVisitor {
70 type Value = Terminator;
71
72 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
73 formatter.write_str(r#""Cr", "Lf", or "CrLf""#)
74 }
75
76 fn visit_str<E>(self, value: &str) -> Result<Terminator, E>
77 where
78 E: de::Error,
79 {
80 match value {
81 "Cr" => Ok(Terminator(er7::Terminator::Cr)),
82 "Lf" => Ok(Terminator(er7::Terminator::Lf)),
83 "CrLf" => Ok(Terminator(er7::Terminator::CrLf)),
84 other => Err(de::Error::unknown_variant(other, &["Cr", "Lf", "CrLf"])),
85 }
86 }
87}
88
89impl<'de> Deserialize<'de> for Terminator {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: Deserializer<'de>,
93 {
94 deserializer.deserialize_str(TerminatorVisitor)
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn round_trips_every_variant() {
104 for terminator in [
105 er7::Terminator::Cr,
106 er7::Terminator::Lf,
107 er7::Terminator::CrLf,
108 ] {
109 let wrapped = Terminator(terminator);
110 let json = serde_json::to_string(&wrapped).unwrap();
111 let back: Terminator = serde_json::from_str(&json).unwrap();
112 assert_eq!(back.0, terminator);
113 }
114 }
115
116 #[test]
117 fn rejects_an_unknown_variant() {
118 assert!(serde_json::from_str::<Terminator>(r#""Sixteen""#).is_err());
119 }
120}