marc_relators/
lib.rs

1//! A crate for serializing and deserializing [MARC relators][marc-relators].
2//!
3//! A MARC record is a [MA-chine Readable Cataloging record][marc]. This crate does not attempt to
4//! deal with records themselves, only with their relators.
5//!
6//! ```rust
7//! use marc_relators::MarcRelator;
8//!
9//! let relator: MarcRelator = "aut".parse().unwrap();
10//! assert_eq!(relator, MarcRelator::Author);
11//!
12//! assert_eq!(relator.code(), "aut");
13//! assert_eq!(relator.name(), "Author");
14//! assert_eq!(
15//!     // The full descriptions can be quite long FYI
16//!     &relator.description().as_bytes()[0..102],
17//!     concat!("A person, family, or organization responsible for ",
18//!             "creating a work that is primarily textual in content").as_bytes(),
19//! );
20//! ```
21//!
22//! This crate tracks the most current MARC specification. At this time, this is MARC 21.
23//!
24//! ## Features
25//!
26//! - `serde`: Enables de/serializatin with [`serde`][serde]. Not enabled by default.
27//!
28//! [marc]: https://www.loc.gov/marc/umb/um01to06.html
29//! [marc-relators]: https://www.loc.gov/marc/relators/relaterm.html.
30//! [serde]: https://serde.rs/
31
32mod inner;
33pub use inner::*;
34use thiserror::Error;
35
36/// An error returned when parsing a string.
37#[derive(Debug, PartialEq, Eq, Error)]
38#[non_exhaustive]
39pub enum ParseError {
40    /// The string was not a known MARC relator code.
41    #[error("unkown code for a MARC relator")]
42    UnknownCode,
43}
44
45#[cfg(test)]
46mod test {
47    use super::MarcRelator;
48
49    #[test]
50    fn from_str() {
51        assert_eq!("aut".parse::<MarcRelator>().unwrap(), MarcRelator::Author);
52    }
53
54    #[test]
55    fn code() {
56        assert_eq!(MarcRelator::Author.code(), "aut");
57    }
58}
59
60#[cfg(feature = "serde")]
61mod marc_serde {
62    use crate::MarcRelator;
63    use serde::de::{self, Deserialize, Deserializer, Visitor};
64    use serde::ser::{Serialize, Serializer};
65    use std::fmt;
66
67    impl Serialize for MarcRelator {
68        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
69        where
70            S: Serializer,
71        {
72            serializer.serialize_str(self.code())
73        }
74    }
75
76    struct MarcRelatorVisitor {}
77
78    impl<'de> Visitor<'de> for MarcRelatorVisitor {
79        type Value = MarcRelator;
80
81        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
82            formatter.write_str("a MARC relator code")
83        }
84
85        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
86        where
87            E: de::Error,
88        {
89            v.parse()
90                .map_err(|_| E::unknown_variant(v, MarcRelator::KNOWN_VARIANTS))
91        }
92    }
93
94    impl<'de> Deserialize<'de> for MarcRelator {
95        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96        where
97            D: Deserializer<'de>,
98        {
99            deserializer.deserialize_str(MarcRelatorVisitor {})
100        }
101    }
102
103    #[cfg(test)]
104    mod test {
105        use crate::MarcRelator;
106        #[test]
107        fn serialize() {
108            assert_eq!(
109                serde_json::to_string(&MarcRelator::Author).unwrap(),
110                "\"aut\""
111            );
112        }
113
114        #[test]
115        fn deserialize() {
116            assert_eq!(
117                serde_json::from_str::<MarcRelator>("\"aut\"").unwrap(),
118                MarcRelator::Author
119            );
120        }
121
122        #[test]
123        fn deserialize_fail() {
124            serde_json::from_str::<MarcRelator>("\"XXX\"").unwrap_err();
125        }
126    }
127}