@@ -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
4142pub use prometheus_client_derive_text_encode:: * ;
@@ -221,6 +222,52 @@ impl Encode for () {
221222 }
222223}
223224
225+ impl Encode for Ipv4Addr {
226+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
227+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
228+ Ok ( ( ) )
229+ }
230+ }
231+
232+ impl Encode for Ipv6Addr {
233+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
234+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
235+ Ok ( ( ) )
236+ }
237+ }
238+
239+ impl Encode for IpAddr {
240+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
241+ match self {
242+ IpAddr :: V4 ( v4) => v4. encode ( writer) ,
243+ IpAddr :: V6 ( v6) => v6. encode ( writer) ,
244+ }
245+ }
246+ }
247+
248+ impl Encode for SocketAddrV4 {
249+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
250+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
251+ Ok ( ( ) )
252+ }
253+ }
254+
255+ impl Encode for SocketAddrV6 {
256+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
257+ writer. write_all ( self . to_string ( ) . as_bytes ( ) ) ?;
258+ Ok ( ( ) )
259+ }
260+ }
261+
262+ impl Encode for SocketAddr {
263+ fn encode ( & self , writer : & mut dyn Write ) -> Result < ( ) , std:: io:: Error > {
264+ match self {
265+ SocketAddr :: V4 ( v4) => v4. encode ( writer) ,
266+ SocketAddr :: V6 ( v6) => v6. encode ( writer) ,
267+ }
268+ }
269+ }
270+
224271/// Helper type for [`EncodeMetric`], see [`EncodeMetric::encode`].
225272///
226273// `Encoder` does not take a trait parameter for `writer` and `labels` because
@@ -720,6 +767,48 @@ mod tests {
720767 parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
721768 }
722769
770+ #[ test]
771+ fn encode_socketaddr ( ) {
772+ let mut registry = Registry :: default ( ) ;
773+ let family = Family :: < Vec < ( & str , SocketAddr ) > , Counter > :: default ( ) ;
774+ registry. register ( "my_addr" , "My socket address" , family. clone ( ) ) ;
775+
776+ let addr: SocketAddr = "127.0.0.1:80" . parse ( ) . unwrap ( ) ;
777+ family. get_or_create ( & vec ! [ ( "address" , addr) ] ) . inc ( ) ;
778+
779+ let mut encoded = Vec :: new ( ) ;
780+ encode ( & mut encoded, & registry) . unwrap ( ) ;
781+
782+ let expected = "# HELP my_addr My socket address.\n " . to_owned ( )
783+ + "# TYPE my_addr counter\n "
784+ + "my_addr_total{address=\" 127.0.0.1:80\" } 1\n "
785+ + "# EOF\n " ;
786+ assert_eq ! ( expected, String :: from_utf8( encoded. clone( ) ) . unwrap( ) ) ;
787+
788+ parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
789+ }
790+
791+ #[ test]
792+ fn encode_ipaddr ( ) {
793+ let mut registry = Registry :: default ( ) ;
794+ let family = Family :: < Vec < ( & str , IpAddr ) > , Counter > :: default ( ) ;
795+ registry. register ( "my_addr" , "My IP address" , family. clone ( ) ) ;
796+
797+ let addr: IpAddr = "::1" . parse ( ) . unwrap ( ) ;
798+ family. get_or_create ( & vec ! [ ( "address" , addr) ] ) . inc ( ) ;
799+
800+ let mut encoded = Vec :: new ( ) ;
801+ encode ( & mut encoded, & registry) . unwrap ( ) ;
802+
803+ let expected = "# HELP my_addr My IP address.\n " . to_owned ( )
804+ + "# TYPE my_addr counter\n "
805+ + "my_addr_total{address=\" ::1\" } 1\n "
806+ + "# EOF\n " ;
807+ assert_eq ! ( expected, String :: from_utf8( encoded. clone( ) ) . unwrap( ) ) ;
808+
809+ parse_with_python_client ( String :: from_utf8 ( encoded) . unwrap ( ) ) ;
810+ }
811+
723812 #[ test]
724813 fn encode_counter_family_with_prefix_with_label ( ) {
725814 let mut registry = Registry :: default ( ) ;
0 commit comments