ferric_fred/
shape_type.rs1use std::fmt;
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum ShapeType {
16 State,
18 County,
20 Msa,
22 Country,
24 Bea,
26 Other(String),
29}
30
31impl ShapeType {
32 fn from_token(token: &str) -> Self {
34 match token {
35 "state" => Self::State,
36 "county" => Self::County,
37 "msa" => Self::Msa,
38 "country" => Self::Country,
39 "bea" => Self::Bea,
40 other => Self::Other(other.to_owned()),
41 }
42 }
43
44 pub fn query_code(&self) -> &str {
48 match self {
49 Self::State => "state",
50 Self::County => "county",
51 Self::Msa => "msa",
52 Self::Country => "country",
53 Self::Bea => "bea",
54 Self::Other(token) => token,
55 }
56 }
57}
58
59impl fmt::Display for ShapeType {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 f.write_str(self.query_code())
62 }
63}
64
65impl<'de> Deserialize<'de> for ShapeType {
66 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
67 where
68 D: Deserializer<'de>,
69 {
70 let token = String::deserialize(deserializer)?;
71 Ok(Self::from_token(&token))
72 }
73}
74
75impl Serialize for ShapeType {
76 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: Serializer,
80 {
81 serializer.serialize_str(self.query_code())
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn known_token_maps_to_variant() {
91 assert_eq!(
92 serde_json::from_str::<ShapeType>("\"bea\"").unwrap(),
93 ShapeType::Bea
94 );
95 }
96
97 #[test]
98 fn unknown_token_is_preserved_verbatim() {
99 assert_eq!(
100 serde_json::from_str::<ShapeType>("\"necta\"").unwrap(),
101 ShapeType::Other("necta".to_owned())
102 );
103 }
104
105 #[test]
106 fn query_codes_match_fred() {
107 assert_eq!(ShapeType::Bea.query_code(), "bea");
108 assert_eq!(ShapeType::State.query_code(), "state");
109 assert_eq!(ShapeType::Other("necta".to_owned()).query_code(), "necta");
110 }
111}