use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Sector {
Battery,
Textile,
UnsoldGoods,
Steel,
Electronics,
Construction,
Tyre,
Toy,
Aluminium,
Furniture,
Detergent,
Other(String),
}
impl Sector {
pub fn catalog_key(&self) -> &str {
match self {
Self::Battery => "battery",
Self::Textile => "textile",
Self::UnsoldGoods => "unsold-goods",
Self::Steel => "steel",
Self::Electronics => "electronics",
Self::Construction => "construction",
Self::Tyre => "tyre",
Self::Toy => "toy",
Self::Aluminium => "aluminium",
Self::Furniture => "furniture",
Self::Detergent => "detergent",
Self::Other(key) => key,
}
}
#[must_use]
pub fn from_wire_tag(tag: &str) -> Self {
match tag {
"battery" => Self::Battery,
"textile" => Self::Textile,
"unsoldGoods" | "unsold-goods" => Self::UnsoldGoods,
"steel" => Self::Steel,
"electronics" => Self::Electronics,
"construction" => Self::Construction,
"tyre" => Self::Tyre,
"toy" => Self::Toy,
"aluminium" => Self::Aluminium,
"furniture" => Self::Furniture,
"detergent" => Self::Detergent,
other => Self::Other(other.to_owned()),
}
}
pub fn wire_str(&self) -> &str {
match self {
Self::Battery => "battery",
Self::Textile => "textile",
Self::UnsoldGoods => "unsoldGoods",
Self::Steel => "steel",
Self::Electronics => "electronics",
Self::Construction => "construction",
Self::Tyre => "tyre",
Self::Toy => "toy",
Self::Aluminium => "aluminium",
Self::Furniture => "furniture",
Self::Detergent => "detergent",
Self::Other(tag) => tag,
}
}
}
impl Serialize for Sector {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.wire_str())
}
}
impl<'de> Deserialize<'de> for Sector {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let tag = String::deserialize(deserializer)?;
Ok(Self::from_wire_tag(&tag))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn wire_str_matches_serde_serialization() {
for sector in [
Sector::Battery,
Sector::Textile,
Sector::UnsoldGoods,
Sector::Steel,
Sector::Electronics,
Sector::Construction,
Sector::Tyre,
Sector::Toy,
Sector::Aluminium,
Sector::Furniture,
Sector::Detergent,
Sector::Other("packaging".into()),
] {
let serialized = serde_json::to_value(§or).unwrap();
assert_eq!(
serialized.as_str().unwrap(),
sector.wire_str(),
"wire_str() disagrees with serde for {sector:?}"
);
}
}
}