1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use mongodb::bson::oid::ObjectId; use serde::{de::Visitor, Deserialize, Serialize}; use std::{fmt::Display, str::FromStr}; use thiserror::Error; pub trait Entity { fn id(&self) -> &ID; fn eq(&self, other: &Self) -> bool { self.id() == other.id() } } #[derive(Debug, Clone)] pub struct ID(ObjectId); impl ID { pub fn new() -> Self { Self(ObjectId::new()) } pub fn from(oid: ObjectId) -> Self { Self(oid) } pub fn as_string(&self) -> String { self.0.to_string() } pub fn inner(self) -> ObjectId { self.0 } pub fn inner_ref(&self) -> &ObjectId { &self.0 } } impl Default for ID { fn default() -> Self { Self::new() } } impl Display for ID { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.as_string()) } } #[derive(Error, Debug)] pub enum InvalidIDError { #[error("ID: {0} is malformed")] Malformed(String), } impl FromStr for ID { type Err = InvalidIDError; fn from_str(s: &str) -> Result<Self, Self::Err> { ObjectId::with_string(s) .map(Self) .map_err(|_| InvalidIDError::Malformed(s.to_string())) } } impl PartialEq for ID { fn eq(&self, other: &Self) -> bool { self.as_string() == other.as_string() } } impl Serialize for ID { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer, { serializer.serialize_str(&self.as_string()) } } impl<'de> Deserialize<'de> for ID { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: serde::Deserializer<'de>, { struct IDVisitor; impl<'de> Visitor<'de> for IDVisitor { type Value = ID; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("A valid string id representation") } fn visit_str<E>(self, value: &str) -> Result<ID, E> where E: serde::de::Error, { value .parse::<ID>() .map_err(|_| E::custom(format!("Malformed id: {}", value))) } } deserializer.deserialize_str(IDVisitor) } }