open_library/models/
identifiers.rs

1use crate::OpenLibraryError;
2use serde;
3use std::fmt::Display;
4use std::str::FromStr;
5
6pub trait Identifier: Display {
7    fn acronym(&self) -> &'static str;
8    fn value(&self) -> &str;
9}
10
11macro_rules! identifier {
12    ($name:ident, $acy: literal) => {
13        #[derive(serde::Serialize, serde::Deserialize, Debug, Eq, PartialEq, Hash, Clone)]
14        #[serde(transparent)]
15        pub struct $name(String);
16
17        impl Identifier for $name {
18            fn acronym(&self) -> &'static str {
19                $acy
20            }
21
22            fn value(&self) -> &str {
23                &self.0.as_str()
24            }
25        }
26
27        impl FromStr for $name {
28            type Err = OpenLibraryError;
29
30            fn from_str(s: &str) -> Result<Self, Self::Err> {
31                Ok($name(s.to_string()))
32            }
33        }
34
35        impl std::fmt::Display for $name {
36            fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
37                self.0.fmt(f)
38            }
39        }
40    };
41}
42
43identifier!(InternationalStandardBookNumber, "ISBN");
44identifier!(OpenLibraryIdentifier, "OLID");