@@ -25,6 +25,22 @@ impl ServerAddr {
2525 Self ( Some ( addr) )
2626 }
2727
28+ /// The hostname portion of the address, without the port. Prefers
29+ /// "localhost" when using a loopback address.
30+ pub fn hostname ( & self ) -> Option < String > {
31+ self . 0 . map ( |addr| {
32+ if addr. ip ( ) . is_loopback ( ) || addr. ip ( ) . is_unspecified ( ) {
33+ "localhost" . to_string ( )
34+ } else if addr. is_ipv6 ( ) {
35+ // When using an IPv6 address, we need to surround the IP in brackets to
36+ // distinguish it from the port's `:`.
37+ format ! ( "[{}]" , addr. ip( ) )
38+ } else {
39+ addr. ip ( ) . to_string ( )
40+ }
41+ } )
42+ }
43+
2844 pub fn ip ( & self ) -> Option < String > {
2945 self . 0 . map ( |addr| addr. ip ( ) . to_string ( ) )
3046 }
@@ -33,18 +49,17 @@ impl ServerAddr {
3349 self . 0 . map ( |addr| addr. port ( ) )
3450 }
3551
52+ /// Constructs a URL out of the address.
3653 pub fn to_string ( & self ) -> Result < String > {
37- let addr = & self . 0 . context ( "expected some server address" ) ?;
38- let uri = if addr. ip ( ) . is_loopback ( ) || addr. ip ( ) . is_unspecified ( ) {
39- match addr. port ( ) {
40- 80 => "http://localhost" . to_string ( ) ,
41- 443 => "https://localhost" . to_string ( ) ,
42- _ => format ! ( "http://localhost:{}" , addr. port( ) ) ,
43- }
44- } else {
45- format ! ( "http://{}" , addr)
46- } ;
47- Ok ( uri)
54+ let ( hostname, port) = self
55+ . hostname ( )
56+ . zip ( self . port ( ) )
57+ . context ( "expected some server address" ) ?;
58+ Ok ( match port {
59+ 80 => format ! ( "http://{hostname}" ) ,
60+ 443 => format ! ( "https://{hostname}" ) ,
61+ _ => format ! ( "http://{hostname}:{port}" ) ,
62+ } )
4863 }
4964}
5065
0 commit comments