@@ -2,7 +2,7 @@ use crate::cmp::Ordering;
2
2
use crate :: convert:: TryInto ;
3
3
use crate :: fmt;
4
4
use crate :: hash;
5
- use crate :: io;
5
+ use crate :: io:: { self , Write } ;
6
6
use crate :: iter;
7
7
use crate :: mem;
8
8
use crate :: net:: { htons, ntohs, IpAddr , Ipv4Addr , Ipv6Addr } ;
@@ -600,7 +600,26 @@ impl fmt::Display for SocketAddr {
600
600
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
601
601
impl fmt:: Display for SocketAddrV4 {
602
602
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
603
- write ! ( f, "{}:{}" , self . ip( ) , self . port( ) )
603
+ // Fast path: if there's no alignment stuff, write to the output buffer
604
+ // directly
605
+ if f. precision ( ) . is_none ( ) && f. width ( ) . is_none ( ) {
606
+ write ! ( f, "{}:{}" , self . ip( ) , self . port( ) )
607
+ } else {
608
+ const IPV4_SOCKET_BUF_LEN : usize = ( 3 * 4 ) // the segments
609
+ + 3 // the separators
610
+ + 1 + 5 ; // the port
611
+ let mut buf = [ 0 ; IPV4_SOCKET_BUF_LEN ] ;
612
+ let mut buf_slice = & mut buf[ ..] ;
613
+
614
+ // Unwrap is fine because writing to a sufficiently-sized
615
+ // buffer is infallible
616
+ write ! ( buf_slice, "{}:{}" , self . ip( ) , self . port( ) ) . unwrap ( ) ;
617
+ let len = IPV4_SOCKET_BUF_LEN - buf_slice. len ( ) ;
618
+
619
+ // This unsafe is OK because we know what is being written to the buffer
620
+ let buf = unsafe { crate :: str:: from_utf8_unchecked ( & buf[ ..len] ) } ;
621
+ f. pad ( buf)
622
+ }
604
623
}
605
624
}
606
625
@@ -614,7 +633,28 @@ impl fmt::Debug for SocketAddrV4 {
614
633
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
615
634
impl fmt:: Display for SocketAddrV6 {
616
635
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
617
- write ! ( f, "[{}]:{}" , self . ip( ) , self . port( ) )
636
+ // Fast path: if there's no alignment stuff, write to the output
637
+ // buffer directly
638
+ if f. precision ( ) . is_none ( ) && f. width ( ) . is_none ( ) {
639
+ write ! ( f, "[{}]:{}" , self . ip( ) , self . port( ) )
640
+ } else {
641
+ const IPV6_SOCKET_BUF_LEN : usize = ( 4 * 8 ) // The address
642
+ + 7 // The colon separators
643
+ + 2 // The brackets
644
+ + 1 + 5 ; // The port
645
+
646
+ let mut buf = [ 0 ; IPV6_SOCKET_BUF_LEN ] ;
647
+ let mut buf_slice = & mut buf[ ..] ;
648
+
649
+ // Unwrap is fine because writing to a sufficiently-sized
650
+ // buffer is infallible
651
+ write ! ( buf_slice, "[{}]:{}" , self . ip( ) , self . port( ) ) . unwrap ( ) ;
652
+ let len = IPV6_SOCKET_BUF_LEN - buf_slice. len ( ) ;
653
+
654
+ // This unsafe is OK because we know what is being written to the buffer
655
+ let buf = unsafe { crate :: str:: from_utf8_unchecked ( & buf[ ..len] ) } ;
656
+ f. pad ( buf)
657
+ }
618
658
}
619
659
}
620
660
@@ -1168,6 +1208,28 @@ mod tests {
1168
1208
assert ! ( v6. is_ipv6( ) ) ;
1169
1209
}
1170
1210
1211
+ #[ test]
1212
+ fn socket_v4_to_str ( ) {
1213
+ let socket = SocketAddrV4 :: new ( Ipv4Addr :: new ( 192 , 168 , 0 , 1 ) , 8080 ) ;
1214
+
1215
+ assert_eq ! ( format!( "{}" , socket) , "192.168.0.1:8080" ) ;
1216
+ assert_eq ! ( format!( "{:<20}" , socket) , "192.168.0.1:8080 " ) ;
1217
+ assert_eq ! ( format!( "{:>20}" , socket) , " 192.168.0.1:8080" ) ;
1218
+ assert_eq ! ( format!( "{:^20}" , socket) , " 192.168.0.1:8080 " ) ;
1219
+ assert_eq ! ( format!( "{:.10}" , socket) , "192.168.0." ) ;
1220
+ }
1221
+
1222
+ #[ test]
1223
+ fn socket_v6_to_str ( ) {
1224
+ let socket: SocketAddrV6 = "[2a02:6b8:0:1::1]:53" . parse ( ) . unwrap ( ) ;
1225
+
1226
+ assert_eq ! ( format!( "{}" , socket) , "[2a02:6b8:0:1::1]:53" ) ;
1227
+ assert_eq ! ( format!( "{:<24}" , socket) , "[2a02:6b8:0:1::1]:53 " ) ;
1228
+ assert_eq ! ( format!( "{:>24}" , socket) , " [2a02:6b8:0:1::1]:53" ) ;
1229
+ assert_eq ! ( format!( "{:^24}" , socket) , " [2a02:6b8:0:1::1]:53 " ) ;
1230
+ assert_eq ! ( format!( "{:.15}" , socket) , "[2a02:6b8:0:1::" ) ;
1231
+ }
1232
+
1171
1233
#[ test]
1172
1234
fn compare ( ) {
1173
1235
let v4_1 = "224.120.45.1:23456" . parse :: < SocketAddrV4 > ( ) . unwrap ( ) ;
0 commit comments