@@ -4,11 +4,10 @@ mod tests;
44
55use crate :: cmp:: Ordering ;
66use crate :: fmt:: { self , Write as FmtWrite } ;
7- use crate :: hash;
87use crate :: io:: Write as IoWrite ;
98use crate :: mem:: transmute;
109use crate :: sys:: net:: netc as c;
11- use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
10+ use crate :: sys_common:: { FromInner , IntoInner } ;
1211
1312/// An IP address, either IPv4 or IPv6.
1413///
@@ -77,10 +76,10 @@ pub enum IpAddr {
7776/// assert!("0000000.0.0.0".parse::<Ipv4Addr>().is_err()); // first octet is a zero in octal
7877/// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex
7978/// ```
80- #[ derive( Copy ) ]
79+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
8180#[ stable( feature = "rust1" , since = "1.0.0" ) ]
8281pub struct Ipv4Addr {
83- inner : c :: in_addr ,
82+ octets : [ u8 ; 4 ] ,
8483}
8584
8685/// An IPv6 address.
@@ -162,10 +161,10 @@ pub struct Ipv4Addr {
162161/// assert_eq!("::1".parse(), Ok(localhost));
163162/// assert_eq!(localhost.is_loopback(), true);
164163/// ```
165- #[ derive( Copy ) ]
164+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
166165#[ stable( feature = "rust1" , since = "1.0.0" ) ]
167166pub struct Ipv6Addr {
168- inner : c :: in6_addr ,
167+ octets : [ u8 ; 16 ] ,
169168}
170169
171170/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2].
@@ -461,9 +460,7 @@ impl Ipv4Addr {
461460 #[ must_use]
462461 #[ inline]
463462 pub const fn new ( a : u8 , b : u8 , c : u8 , d : u8 ) -> Ipv4Addr {
464- // `s_addr` is stored as BE on all machine and the array is in BE order.
465- // So the native endian conversion method is used so that it's never swapped.
466- Ipv4Addr { inner : c:: in_addr { s_addr : u32:: from_ne_bytes ( [ a, b, c, d] ) } }
463+ Ipv4Addr { octets : [ a, b, c, d] }
467464 }
468465
469466 /// An IPv4 address with the address pointing to localhost: `127.0.0.1`
@@ -523,8 +520,7 @@ impl Ipv4Addr {
523520 #[ must_use]
524521 #[ inline]
525522 pub const fn octets ( & self ) -> [ u8 ; 4 ] {
526- // This returns the order we want because s_addr is stored in big-endian.
527- self . inner . s_addr . to_ne_bytes ( )
523+ self . octets
528524 }
529525
530526 /// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
@@ -547,7 +543,7 @@ impl Ipv4Addr {
547543 #[ must_use]
548544 #[ inline]
549545 pub const fn is_unspecified ( & self ) -> bool {
550- self . inner . s_addr == 0
546+ u32 :: from_be_bytes ( self . octets ) == 0
551547 }
552548
553549 /// Returns [`true`] if this is a loopback address (`127.0.0.0/8`).
@@ -910,9 +906,7 @@ impl Ipv4Addr {
910906 #[ inline]
911907 pub const fn to_ipv6_compatible ( & self ) -> Ipv6Addr {
912908 let [ a, b, c, d] = self . octets ( ) ;
913- Ipv6Addr {
914- inner : c:: in6_addr { s6_addr : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , a, b, c, d] } ,
915- }
909+ Ipv6Addr { octets : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , a, b, c, d] }
916910 }
917911
918912 /// Converts this address to an [IPv4-mapped] [`IPv6` address].
@@ -937,9 +931,7 @@ impl Ipv4Addr {
937931 #[ inline]
938932 pub const fn to_ipv6_mapped ( & self ) -> Ipv6Addr {
939933 let [ a, b, c, d] = self . octets ( ) ;
940- Ipv6Addr {
941- inner : c:: in6_addr { s6_addr : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF , a, b, c, d] } ,
942- }
934+ Ipv6Addr { octets : [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF , a, b, c, d] }
943935 }
944936}
945937
@@ -1034,22 +1026,6 @@ impl fmt::Debug for Ipv4Addr {
10341026 }
10351027}
10361028
1037- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1038- impl Clone for Ipv4Addr {
1039- #[ inline]
1040- fn clone ( & self ) -> Ipv4Addr {
1041- * self
1042- }
1043- }
1044-
1045- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1046- impl PartialEq for Ipv4Addr {
1047- #[ inline]
1048- fn eq ( & self , other : & Ipv4Addr ) -> bool {
1049- self . inner . s_addr == other. inner . s_addr
1050- }
1051- }
1052-
10531029#[ stable( feature = "ip_cmp" , since = "1.16.0" ) ]
10541030impl PartialEq < Ipv4Addr > for IpAddr {
10551031 #[ inline]
@@ -1072,21 +1048,6 @@ impl PartialEq<IpAddr> for Ipv4Addr {
10721048 }
10731049}
10741050
1075- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1076- impl Eq for Ipv4Addr { }
1077-
1078- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1079- impl hash:: Hash for Ipv4Addr {
1080- #[ inline]
1081- fn hash < H : hash:: Hasher > ( & self , s : & mut H ) {
1082- // NOTE:
1083- // * hash in big endian order
1084- // * in netbsd, `in_addr` has `repr(packed)`, we need to
1085- // copy `s_addr` to avoid unsafe borrowing
1086- { self . inner . s_addr } . hash ( s)
1087- }
1088- }
1089-
10901051#[ stable( feature = "rust1" , since = "1.0.0" ) ]
10911052impl PartialOrd for Ipv4Addr {
10921053 #[ inline]
@@ -1121,15 +1082,21 @@ impl PartialOrd<IpAddr> for Ipv4Addr {
11211082impl Ord for Ipv4Addr {
11221083 #[ inline]
11231084 fn cmp ( & self , other : & Ipv4Addr ) -> Ordering {
1124- // Compare as native endian
1125- u32:: from_be ( self . inner . s_addr ) . cmp ( & u32:: from_be ( other. inner . s_addr ) )
1085+ self . octets . cmp ( & other. octets )
11261086 }
11271087}
11281088
11291089impl IntoInner < c:: in_addr > for Ipv4Addr {
11301090 #[ inline]
11311091 fn into_inner ( self ) -> c:: in_addr {
1132- self . inner
1092+ // `s_addr` is stored as BE on all machines and the array is in BE order.
1093+ // So the native endian conversion method is used so that it's never swapped.
1094+ c:: in_addr { s_addr : u32:: from_ne_bytes ( self . octets ) }
1095+ }
1096+ }
1097+ impl FromInner < c:: in_addr > for Ipv4Addr {
1098+ fn from_inner ( addr : c:: in_addr ) -> Ipv4Addr {
1099+ Ipv4Addr { octets : addr. s_addr . to_ne_bytes ( ) }
11331100 }
11341101}
11351102
@@ -1147,8 +1114,7 @@ impl From<Ipv4Addr> for u32 {
11471114 /// ```
11481115 #[ inline]
11491116 fn from ( ip : Ipv4Addr ) -> u32 {
1150- let ip = ip. octets ( ) ;
1151- u32:: from_be_bytes ( ip)
1117+ u32:: from_be_bytes ( ip. octets )
11521118 }
11531119}
11541120
@@ -1166,7 +1132,7 @@ impl From<u32> for Ipv4Addr {
11661132 /// ```
11671133 #[ inline]
11681134 fn from ( ip : u32 ) -> Ipv4Addr {
1169- Ipv4Addr :: from ( ip. to_be_bytes ( ) )
1135+ Ipv4Addr { octets : ip. to_be_bytes ( ) }
11701136 }
11711137}
11721138
@@ -1184,7 +1150,7 @@ impl From<[u8; 4]> for Ipv4Addr {
11841150 /// ```
11851151 #[ inline]
11861152 fn from ( octets : [ u8 ; 4 ] ) -> Ipv4Addr {
1187- Ipv4Addr :: new ( octets [ 0 ] , octets [ 1 ] , octets[ 2 ] , octets [ 3 ] )
1153+ Ipv4Addr { octets }
11881154 }
11891155}
11901156
@@ -1234,13 +1200,9 @@ impl Ipv6Addr {
12341200 h. to_be ( ) ,
12351201 ] ;
12361202 Ipv6Addr {
1237- inner : c:: in6_addr {
1238- // All elements in `addr16` are big endian.
1239- // SAFETY: `[u16; 8]` is always safe to transmute to `[u8; 16]`.
1240- // rustc_allow_const_fn_unstable: the transmute could be written as stable const
1241- // code, but that leads to worse code generation (#75085)
1242- s6_addr : unsafe { transmute :: < _ , [ u8 ; 16 ] > ( addr16) } ,
1243- } ,
1203+ // All elements in `addr16` are big endian.
1204+ // SAFETY: `[u16; 8]` is always safe to transmute to `[u8; 16]`.
1205+ octets : unsafe { transmute :: < _ , [ u8 ; 16 ] > ( addr16) } ,
12441206 }
12451207 }
12461208
@@ -1285,11 +1247,9 @@ impl Ipv6Addr {
12851247 #[ must_use]
12861248 #[ inline]
12871249 pub const fn segments ( & self ) -> [ u16 ; 8 ] {
1288- // All elements in `s6_addr ` must be big endian.
1250+ // All elements in `self.octets ` must be big endian.
12891251 // SAFETY: `[u8; 16]` is always safe to transmute to `[u16; 8]`.
1290- // rustc_allow_const_fn_unstable: the transmute could be written as stable const code, but
1291- // that leads to worse code generation (#75085)
1292- let [ a, b, c, d, e, f, g, h] = unsafe { transmute :: < _ , [ u16 ; 8 ] > ( self . inner . s6_addr ) } ;
1252+ let [ a, b, c, d, e, f, g, h] = unsafe { transmute :: < _ , [ u16 ; 8 ] > ( self . octets ) } ;
12931253 // We want native endian u16
12941254 [
12951255 u16:: from_be ( a) ,
@@ -1748,7 +1708,7 @@ impl Ipv6Addr {
17481708 #[ must_use]
17491709 #[ inline]
17501710 pub const fn octets ( & self ) -> [ u8 ; 16 ] {
1751- self . inner . s6_addr
1711+ self . octets
17521712 }
17531713}
17541714
@@ -1856,22 +1816,6 @@ impl fmt::Debug for Ipv6Addr {
18561816 }
18571817}
18581818
1859- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1860- impl Clone for Ipv6Addr {
1861- #[ inline]
1862- fn clone ( & self ) -> Ipv6Addr {
1863- * self
1864- }
1865- }
1866-
1867- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1868- impl PartialEq for Ipv6Addr {
1869- #[ inline]
1870- fn eq ( & self , other : & Ipv6Addr ) -> bool {
1871- self . inner . s6_addr == other. inner . s6_addr
1872- }
1873- }
1874-
18751819#[ stable( feature = "ip_cmp" , since = "1.16.0" ) ]
18761820impl PartialEq < IpAddr > for Ipv6Addr {
18771821 #[ inline]
@@ -1894,17 +1838,6 @@ impl PartialEq<Ipv6Addr> for IpAddr {
18941838 }
18951839}
18961840
1897- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1898- impl Eq for Ipv6Addr { }
1899-
1900- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1901- impl hash:: Hash for Ipv6Addr {
1902- #[ inline]
1903- fn hash < H : hash:: Hasher > ( & self , s : & mut H ) {
1904- self . inner . s6_addr . hash ( s)
1905- }
1906- }
1907-
19081841#[ stable( feature = "rust1" , since = "1.0.0" ) ]
19091842impl PartialOrd for Ipv6Addr {
19101843 #[ inline]
@@ -1943,16 +1876,15 @@ impl Ord for Ipv6Addr {
19431876 }
19441877}
19451878
1946- impl AsInner < c:: in6_addr > for Ipv6Addr {
1947- #[ inline]
1948- fn as_inner ( & self ) -> & c:: in6_addr {
1949- & self . inner
1879+ impl IntoInner < c:: in6_addr > for Ipv6Addr {
1880+ fn into_inner ( self ) -> c:: in6_addr {
1881+ c:: in6_addr { s6_addr : self . octets }
19501882 }
19511883}
19521884impl FromInner < c:: in6_addr > for Ipv6Addr {
19531885 #[ inline]
19541886 fn from_inner ( addr : c:: in6_addr ) -> Ipv6Addr {
1955- Ipv6Addr { inner : addr }
1887+ Ipv6Addr { octets : addr. s6_addr }
19561888 }
19571889}
19581890
@@ -1973,8 +1905,7 @@ impl From<Ipv6Addr> for u128 {
19731905 /// ```
19741906 #[ inline]
19751907 fn from ( ip : Ipv6Addr ) -> u128 {
1976- let ip = ip. octets ( ) ;
1977- u128:: from_be_bytes ( ip)
1908+ u128:: from_be_bytes ( ip. octets )
19781909 }
19791910}
19801911#[ stable( feature = "i128" , since = "1.26.0" ) ]
@@ -2025,8 +1956,7 @@ impl From<[u8; 16]> for Ipv6Addr {
20251956 /// ```
20261957 #[ inline]
20271958 fn from ( octets : [ u8 ; 16 ] ) -> Ipv6Addr {
2028- let inner = c:: in6_addr { s6_addr : octets } ;
2029- Ipv6Addr :: from_inner ( inner)
1959+ Ipv6Addr { octets }
20301960 }
20311961}
20321962
0 commit comments