@@ -36,6 +36,7 @@ use crate::registry::{Registry, Unit};
3636use std:: borrow:: Cow ;
3737use std:: collections:: HashMap ;
3838use std:: io:: Write ;
39+ use std:: net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr , SocketAddrV4 , SocketAddrV6 } ;
3940use std:: ops:: Deref ;
4041
4142/// Encode the metrics registered with the provided [`Registry`] into the
@@ -206,6 +207,52 @@ impl Encode for () {
206207 }
207208}
208209
210+ impl Encode for Ipv4Addr {
211+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
212+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
213+ Ok ( ( ) )
214+ }
215+ }
216+
217+ impl Encode for Ipv6Addr {
218+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
219+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
220+ Ok ( ( ) )
221+ }
222+ }
223+
224+ impl Encode for IpAddr {
225+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
226+ match self {
227+ IpAddr :: V4 ( v4) => v4. encode ( writer) ,
228+ IpAddr :: V6 ( v6) => v6. encode ( writer) ,
229+ }
230+ }
231+ }
232+
233+ impl Encode for SocketAddrV4 {
234+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
235+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
236+ Ok ( ( ) )
237+ }
238+ }
239+
240+ impl Encode for SocketAddrV6 {
241+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
242+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
243+ Ok ( ( ) )
244+ }
245+ }
246+
247+ impl Encode for SocketAddr {
248+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
249+ match self {
250+ SocketAddr :: V4 ( v4) => v4. encode ( writer) ,
251+ SocketAddr :: V6 ( v6) => v6. encode ( writer) ,
252+ }
253+ }
254+ }
255+
209256/// Helper type for [`EncodeMetric`], see [`EncodeMetric::encode`].
210257///
211258// `Encoder` does not take a trait parameter for `writer` and `labels` because
@@ -705,6 +752,48 @@ mod tests {
705752 parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
706753 }
707754
755+ #[ test]
756+ fn encode_socketaddr ( ) {
757+ let mut registry = Registry :: default ( ) ;
758+ let family = Family :: < Vec < ( & str , SocketAddr ) > , Counter > :: default ( ) ;
759+ registry. register ( "my_addr" , "My socket address" , family. clone ( ) ) ;
760+
761+ let addr: SocketAddr = "127.0.0.1:80" . parse ( ) . unwrap ( ) ;
762+ family. get_or_create ( & vec ! [ ( "address" , addr) ] ) . inc ( ) ;
763+
764+ let mut encoded = Vec :: new ( ) ;
765+ encode ( & mut encoded, & registry) . unwrap ( ) ;
766+
767+ let expected = "# HELP my_addr My socket address.\n " . to_owned ( )
768+ + "# TYPE my_addr counter\n "
769+ + "my_addr_total{address=\" 127.0.0.1:80\" } 1\n "
770+ + "# EOF\n " ;
771+ assert_eq ! ( expected, String :: from_utf8( encoded. clone( ) ) . unwrap( ) ) ;
772+
773+ parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
774+ }
775+
776+ #[ test]
777+ fn encode_ipaddr ( ) {
778+ let mut registry = Registry :: default ( ) ;
779+ let family = Family :: < Vec < ( & str , IpAddr ) > , Counter > :: default ( ) ;
780+ registry. register ( "my_addr" , "My IP address" , family. clone ( ) ) ;
781+
782+ let addr: IpAddr = "::1" . parse ( ) . unwrap ( ) ;
783+ family. get_or_create ( & vec ! [ ( "address" , addr) ] ) . inc ( ) ;
784+
785+ let mut encoded = Vec :: new ( ) ;
786+ encode ( & mut encoded, & registry) . unwrap ( ) ;
787+
788+ let expected = "# HELP my_addr My IP address.\n " . to_owned ( )
789+ + "# TYPE my_addr counter\n "
790+ + "my_addr_total{address=\" ::1\" } 1\n "
791+ + "# EOF\n " ;
792+ assert_eq ! ( expected, String :: from_utf8( encoded. clone( ) ) . unwrap( ) ) ;
793+
794+ parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
795+ }
796+
708797 #[ test]
709798 fn encode_counter_family_with_prefix_with_label ( ) {
710799 let mut registry = Registry :: default ( ) ;
0 commit comments