Skip to content

Commit 8bce240

Browse files
authored
Rollup merge of #72398 - Lucretiel:ip-socket-display, r=Mark-Simulacrum
SocketAddr and friends now correctly pad its content Currently, `IpAddr` and friends correctly respect formatting parameters when printing via `Display`. This PR makes SocketAddr and friends do the same thing.
2 parents 9c1f203 + 06a97a0 commit 8bce240

File tree

1 file changed

+65
-3
lines changed

1 file changed

+65
-3
lines changed

src/libstd/net/addr.rs

+65-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::cmp::Ordering;
22
use crate::convert::TryInto;
33
use crate::fmt;
44
use crate::hash;
5-
use crate::io;
5+
use crate::io::{self, Write};
66
use crate::iter;
77
use crate::mem;
88
use crate::net::{htons, ntohs, IpAddr, Ipv4Addr, Ipv6Addr};
@@ -600,7 +600,26 @@ impl fmt::Display for SocketAddr {
600600
#[stable(feature = "rust1", since = "1.0.0")]
601601
impl fmt::Display for SocketAddrV4 {
602602
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+
}
604623
}
605624
}
606625

@@ -614,7 +633,28 @@ impl fmt::Debug for SocketAddrV4 {
614633
#[stable(feature = "rust1", since = "1.0.0")]
615634
impl fmt::Display for SocketAddrV6 {
616635
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+
}
618658
}
619659
}
620660

@@ -1168,6 +1208,28 @@ mod tests {
11681208
assert!(v6.is_ipv6());
11691209
}
11701210

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+
11711233
#[test]
11721234
fn compare() {
11731235
let v4_1 = "224.120.45.1:23456".parse::<SocketAddrV4>().unwrap();

0 commit comments

Comments
 (0)