Skip to content
This repository was archived by the owner on Jan 2, 2026. It is now read-only.

Commit 66e8ee0

Browse files
author
bitfl0wer
committed
derive deserialize, serialize for federationid
1 parent 377b1ac commit 66e8ee0

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/types/federation_id.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::Constrained;
1111
pub static REGEX_FEDERATION_ID: &str = r"\b([a-z0-9._%+-]+)@([a-z0-9-]+(\.[a-z0-9-]+)*)$";
1212

1313
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
14+
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
1415
/// A `FederationId` is a globally unique identifier for an actor in the context of polyproto.
1516
pub struct FederationId {
1617
/// Must be unique on each instance.
@@ -49,8 +50,52 @@ impl FederationId {
4950
}
5051
}
5152

53+
impl TryFrom<&str> for FederationId {
54+
type Error = ConstraintError;
55+
56+
fn try_from(value: &str) -> Result<Self, Self::Error> {
57+
FederationId::new(value)
58+
}
59+
}
60+
5261
impl std::fmt::Display for FederationId {
5362
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
5463
write!(f, "{}@{}", self.local_name, self.domain_name)
5564
}
5665
}
66+
67+
#[cfg(feature = "serde")]
68+
mod serde {
69+
use serde::de::Visitor;
70+
use serde::Deserialize;
71+
72+
use crate::errors::ERR_MSG_FEDERATION_ID_REGEX;
73+
74+
use super::FederationId;
75+
76+
struct FidVisitor;
77+
78+
impl Visitor<'_> for FidVisitor {
79+
type Value = FederationId;
80+
81+
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
82+
formatter.write_str("a valid polyproto federation ID")
83+
}
84+
85+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
86+
where
87+
E: serde::de::Error,
88+
{
89+
FederationId::new(v).map_err(|_| E::custom(ERR_MSG_FEDERATION_ID_REGEX.to_string()))
90+
}
91+
}
92+
93+
impl<'de> Deserialize<'de> for FederationId {
94+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95+
where
96+
D: serde::Deserializer<'de>,
97+
{
98+
deserializer.deserialize_str(FidVisitor)
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)