@@ -4,11 +4,10 @@ mod tests;
4
4
5
5
use crate :: cmp:: Ordering ;
6
6
use crate :: fmt:: { self , Write as FmtWrite } ;
7
- use crate :: hash;
8
7
use crate :: io:: Write as IoWrite ;
9
8
use crate :: mem:: transmute;
10
9
use crate :: sys:: net:: netc as c;
11
- use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
10
+ use crate :: sys_common:: { FromInner , IntoInner } ;
12
11
13
12
/// An IP address, either IPv4 or IPv6.
14
13
///
@@ -77,10 +76,10 @@ pub enum IpAddr {
77
76
/// assert!("0000000.0.0.0".parse::<Ipv4Addr>().is_err()); // first octet is a zero in octal
78
77
/// assert!("0xcb.0x0.0x71.0x00".parse::<Ipv4Addr>().is_err()); // all octets are in hex
79
78
/// ```
80
- #[ derive( Copy ) ]
79
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
81
80
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
82
81
pub struct Ipv4Addr {
83
- inner : c :: in_addr ,
82
+ octets : [ u8 ; 4 ] ,
84
83
}
85
84
86
85
/// An IPv6 address.
@@ -162,10 +161,10 @@ pub struct Ipv4Addr {
162
161
/// assert_eq!("::1".parse(), Ok(localhost));
163
162
/// assert_eq!(localhost.is_loopback(), true);
164
163
/// ```
165
- #[ derive( Copy ) ]
164
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
166
165
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
167
166
pub struct Ipv6Addr {
168
- inner : c :: in6_addr ,
167
+ octets : [ u8 ; 16 ] ,
169
168
}
170
169
171
170
/// Scope of an [IPv6 multicast address] as defined in [IETF RFC 7346 section 2].
@@ -461,9 +460,7 @@ impl Ipv4Addr {
461
460
#[ must_use]
462
461
#[ inline]
463
462
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] }
467
464
}
468
465
469
466
/// An IPv4 address with the address pointing to localhost: `127.0.0.1`
@@ -523,8 +520,7 @@ impl Ipv4Addr {
523
520
#[ must_use]
524
521
#[ inline]
525
522
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
528
524
}
529
525
530
526
/// Returns [`true`] for the special 'unspecified' address (`0.0.0.0`).
@@ -547,7 +543,7 @@ impl Ipv4Addr {
547
543
#[ must_use]
548
544
#[ inline]
549
545
pub const fn is_unspecified ( & self ) -> bool {
550
- self . inner . s_addr == 0
546
+ u32 :: from_be_bytes ( self . octets ) == 0
551
547
}
552
548
553
549
/// Returns [`true`] if this is a loopback address (`127.0.0.0/8`).
@@ -910,9 +906,7 @@ impl Ipv4Addr {
910
906
#[ inline]
911
907
pub const fn to_ipv6_compatible ( & self ) -> Ipv6Addr {
912
908
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] }
916
910
}
917
911
918
912
/// Converts this address to an [IPv4-mapped] [`IPv6` address].
@@ -937,9 +931,7 @@ impl Ipv4Addr {
937
931
#[ inline]
938
932
pub const fn to_ipv6_mapped ( & self ) -> Ipv6Addr {
939
933
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] }
943
935
}
944
936
}
945
937
@@ -1034,22 +1026,6 @@ impl fmt::Debug for Ipv4Addr {
1034
1026
}
1035
1027
}
1036
1028
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
-
1053
1029
#[ stable( feature = "ip_cmp" , since = "1.16.0" ) ]
1054
1030
impl PartialEq < Ipv4Addr > for IpAddr {
1055
1031
#[ inline]
@@ -1072,21 +1048,6 @@ impl PartialEq<IpAddr> for Ipv4Addr {
1072
1048
}
1073
1049
}
1074
1050
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
-
1090
1051
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1091
1052
impl PartialOrd for Ipv4Addr {
1092
1053
#[ inline]
@@ -1121,15 +1082,21 @@ impl PartialOrd<IpAddr> for Ipv4Addr {
1121
1082
impl Ord for Ipv4Addr {
1122
1083
#[ inline]
1123
1084
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 )
1126
1086
}
1127
1087
}
1128
1088
1129
1089
impl IntoInner < c:: in_addr > for Ipv4Addr {
1130
1090
#[ inline]
1131
1091
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 ( ) }
1133
1100
}
1134
1101
}
1135
1102
@@ -1147,8 +1114,7 @@ impl From<Ipv4Addr> for u32 {
1147
1114
/// ```
1148
1115
#[ inline]
1149
1116
fn from ( ip : Ipv4Addr ) -> u32 {
1150
- let ip = ip. octets ( ) ;
1151
- u32:: from_be_bytes ( ip)
1117
+ u32:: from_be_bytes ( ip. octets )
1152
1118
}
1153
1119
}
1154
1120
@@ -1166,7 +1132,7 @@ impl From<u32> for Ipv4Addr {
1166
1132
/// ```
1167
1133
#[ inline]
1168
1134
fn from ( ip : u32 ) -> Ipv4Addr {
1169
- Ipv4Addr :: from ( ip. to_be_bytes ( ) )
1135
+ Ipv4Addr { octets : ip. to_be_bytes ( ) }
1170
1136
}
1171
1137
}
1172
1138
@@ -1184,7 +1150,7 @@ impl From<[u8; 4]> for Ipv4Addr {
1184
1150
/// ```
1185
1151
#[ inline]
1186
1152
fn from ( octets : [ u8 ; 4 ] ) -> Ipv4Addr {
1187
- Ipv4Addr :: new ( octets [ 0 ] , octets [ 1 ] , octets[ 2 ] , octets [ 3 ] )
1153
+ Ipv4Addr { octets }
1188
1154
}
1189
1155
}
1190
1156
@@ -1234,13 +1200,9 @@ impl Ipv6Addr {
1234
1200
h. to_be ( ) ,
1235
1201
] ;
1236
1202
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) } ,
1244
1206
}
1245
1207
}
1246
1208
@@ -1285,11 +1247,9 @@ impl Ipv6Addr {
1285
1247
#[ must_use]
1286
1248
#[ inline]
1287
1249
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.
1289
1251
// 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 ) } ;
1293
1253
// We want native endian u16
1294
1254
[
1295
1255
u16:: from_be ( a) ,
@@ -1748,7 +1708,7 @@ impl Ipv6Addr {
1748
1708
#[ must_use]
1749
1709
#[ inline]
1750
1710
pub const fn octets ( & self ) -> [ u8 ; 16 ] {
1751
- self . inner . s6_addr
1711
+ self . octets
1752
1712
}
1753
1713
}
1754
1714
@@ -1856,22 +1816,6 @@ impl fmt::Debug for Ipv6Addr {
1856
1816
}
1857
1817
}
1858
1818
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
-
1875
1819
#[ stable( feature = "ip_cmp" , since = "1.16.0" ) ]
1876
1820
impl PartialEq < IpAddr > for Ipv6Addr {
1877
1821
#[ inline]
@@ -1894,17 +1838,6 @@ impl PartialEq<Ipv6Addr> for IpAddr {
1894
1838
}
1895
1839
}
1896
1840
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
-
1908
1841
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1909
1842
impl PartialOrd for Ipv6Addr {
1910
1843
#[ inline]
@@ -1943,16 +1876,15 @@ impl Ord for Ipv6Addr {
1943
1876
}
1944
1877
}
1945
1878
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 }
1950
1882
}
1951
1883
}
1952
1884
impl FromInner < c:: in6_addr > for Ipv6Addr {
1953
1885
#[ inline]
1954
1886
fn from_inner ( addr : c:: in6_addr ) -> Ipv6Addr {
1955
- Ipv6Addr { inner : addr }
1887
+ Ipv6Addr { octets : addr. s6_addr }
1956
1888
}
1957
1889
}
1958
1890
@@ -1973,8 +1905,7 @@ impl From<Ipv6Addr> for u128 {
1973
1905
/// ```
1974
1906
#[ inline]
1975
1907
fn from ( ip : Ipv6Addr ) -> u128 {
1976
- let ip = ip. octets ( ) ;
1977
- u128:: from_be_bytes ( ip)
1908
+ u128:: from_be_bytes ( ip. octets )
1978
1909
}
1979
1910
}
1980
1911
#[ stable( feature = "i128" , since = "1.26.0" ) ]
@@ -2025,8 +1956,7 @@ impl From<[u8; 16]> for Ipv6Addr {
2025
1956
/// ```
2026
1957
#[ inline]
2027
1958
fn from ( octets : [ u8 ; 16 ] ) -> Ipv6Addr {
2028
- let inner = c:: in6_addr { s6_addr : octets } ;
2029
- Ipv6Addr :: from_inner ( inner)
1959
+ Ipv6Addr { octets }
2030
1960
}
2031
1961
}
2032
1962
0 commit comments