@@ -11,6 +11,7 @@ use crate::Constrained;
1111pub 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.
1516pub 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+
5261impl 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