1414
1515use crate :: bgp:: msg_notification:: { BgpError , UpdateMessageError } ;
1616use crate :: bgp:: utils:: ParserError ;
17+ use serde:: { Deserialize , Serialize } ;
1718use std:: fmt;
1819
1920/// Address Family Identifier per IANA registry
@@ -24,6 +25,19 @@ pub enum Afi {
2425 Ipv6 = 2 ,
2526}
2627
28+ impl Serialize for Afi {
29+ fn serialize < S : serde:: Serializer > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > {
30+ serializer. serialize_u16 ( * self as u16 )
31+ }
32+ }
33+
34+ impl < ' de > Deserialize < ' de > for Afi {
35+ fn deserialize < D : serde:: Deserializer < ' de > > ( deserializer : D ) -> Result < Self , D :: Error > {
36+ let value = u16:: deserialize ( deserializer) ?;
37+ Afi :: try_from ( value) . map_err ( |_| serde:: de:: Error :: custom ( format ! ( "unknown AFI: {value}" ) ) )
38+ }
39+ }
40+
2741impl fmt:: Display for Afi {
2842 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
2943 match self {
@@ -57,6 +71,26 @@ pub enum Safi {
5771 MplsLabel = 4 ,
5872}
5973
74+ impl From < Safi > for u8 {
75+ fn from ( safi : Safi ) -> u8 {
76+ safi as u8
77+ }
78+ }
79+
80+ impl Serialize for Safi {
81+ fn serialize < S : serde:: Serializer > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > {
82+ serializer. serialize_u8 ( * self as u8 )
83+ }
84+ }
85+
86+ impl < ' de > Deserialize < ' de > for Safi {
87+ fn deserialize < D : serde:: Deserializer < ' de > > ( deserializer : D ) -> Result < Self , D :: Error > {
88+ let value = u8:: deserialize ( deserializer) ?;
89+ Safi :: try_from ( value)
90+ . map_err ( |_| serde:: de:: Error :: custom ( format ! ( "unknown SAFI: {value}" ) ) )
91+ }
92+ }
93+
6094impl fmt:: Display for Safi {
6195 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
6296 match self {
@@ -84,7 +118,7 @@ impl TryFrom<u8> for Safi {
84118}
85119
86120/// Combined AFI/SAFI for capability tracking
87- #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
121+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash , Serialize , Deserialize ) ]
88122pub struct AfiSafi {
89123 pub afi : Afi ,
90124 pub safi : Safi ,
@@ -119,6 +153,14 @@ impl fmt::Display for AfiSafi {
119153 }
120154}
121155
156+ /// Default AFI/SAFIs: IPv4 Unicast + IPv6 Unicast
157+ pub fn default_afi_safis ( ) -> Vec < AfiSafi > {
158+ vec ! [
159+ AfiSafi :: new( Afi :: Ipv4 , Safi :: Unicast ) ,
160+ AfiSafi :: new( Afi :: Ipv6 , Safi :: Unicast ) ,
161+ ]
162+ }
163+
122164#[ cfg( test) ]
123165mod tests {
124166 use super :: * ;
@@ -165,6 +207,21 @@ mod tests {
165207 assert ! ( AfiSafi :: from_capability_bytes( & bytes) . is_err( ) ) ;
166208 }
167209
210+ #[ test]
211+ fn test_afi_safi_serde_roundtrip ( ) {
212+ let cases = vec ! [
213+ AfiSafi :: new( Afi :: Ipv4 , Safi :: Unicast ) ,
214+ AfiSafi :: new( Afi :: Ipv6 , Safi :: Unicast ) ,
215+ AfiSafi :: new( Afi :: Ipv4 , Safi :: Multicast ) ,
216+ AfiSafi :: new( Afi :: Ipv6 , Safi :: Multicast ) ,
217+ ] ;
218+ for afi_safi in cases {
219+ let json = serde_json:: to_string ( & afi_safi) . unwrap ( ) ;
220+ let parsed: AfiSafi = serde_json:: from_str ( & json) . unwrap ( ) ;
221+ assert_eq ! ( parsed, afi_safi) ;
222+ }
223+ }
224+
168225 #[ test]
169226 fn test_display ( ) {
170227 assert_eq ! ( format!( "{}" , Afi :: Ipv4 ) , "IPv4" ) ;
0 commit comments