A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://doc.rust-lang.org/nightly/src/core/net/ip_addr.rs.html below:

ip_addr.rs - source

1use super::display_buffer::DisplayBuffer;
2use crate::cmp::Ordering;
3use crate::fmt::{self, Write};
4use crate::hash::{Hash, Hasher};
5use crate::mem::transmute;
6use crate::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Not};
7
8#[rustc_diagnostic_item = "IpAddr"]
28#[stable(feature = "ip_addr", since = "1.7.0")]
29#[derive(Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
30pub enum IpAddr {
31    #[stable(feature = "ip_addr", since = "1.7.0")]
33    V4(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv4Addr),
34    #[stable(feature = "ip_addr", since = "1.7.0")]
36    V6(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv6Addr),
37}
38
39#[rustc_diagnostic_item = "Ipv4Addr"]
71#[derive(Copy, Clone, PartialEq, Eq)]
72#[stable(feature = "rust1", since = "1.0.0")]
73pub struct Ipv4Addr {
74    octets: [u8; 4],
75}
76
77#[stable(feature = "rust1", since = "1.0.0")]
78impl Hash for Ipv4Addr {
79    fn hash<H: Hasher>(&self, state: &mut H) {
80        u32::from_ne_bytes(self.octets).hash(state);
84    }
85}
86
87#[rustc_diagnostic_item = "Ipv6Addr"]
164#[derive(Copy, Clone, PartialEq, Eq)]
165#[stable(feature = "rust1", since = "1.0.0")]
166pub struct Ipv6Addr {
167    octets: [u8; 16],
168}
169
170#[stable(feature = "rust1", since = "1.0.0")]
171impl Hash for Ipv6Addr {
172    fn hash<H: Hasher>(&self, state: &mut H) {
173        u128::from_ne_bytes(self.octets).hash(state);
177    }
178}
179
180#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug)]
216#[unstable(feature = "ip", issue = "27709")]
217#[non_exhaustive]
218pub enum Ipv6MulticastScope {
219    InterfaceLocal,
221    LinkLocal,
223    RealmLocal,
225    AdminLocal,
227    SiteLocal,
229    OrganizationLocal,
231    Global,
233}
234
235impl IpAddr {
236    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
250    #[stable(feature = "ip_shared", since = "1.12.0")]
251    #[must_use]
252    #[inline]
253    pub const fn is_unspecified(&self) -> bool {
254        match self {
255            IpAddr::V4(ip) => ip.is_unspecified(),
256            IpAddr::V6(ip) => ip.is_unspecified(),
257        }
258    }
259
260    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
274    #[stable(feature = "ip_shared", since = "1.12.0")]
275    #[must_use]
276    #[inline]
277    pub const fn is_loopback(&self) -> bool {
278        match self {
279            IpAddr::V4(ip) => ip.is_loopback(),
280            IpAddr::V6(ip) => ip.is_loopback(),
281        }
282    }
283
284    #[unstable(feature = "ip", issue = "27709")]
300    #[must_use]
301    #[inline]
302    pub const fn is_global(&self) -> bool {
303        match self {
304            IpAddr::V4(ip) => ip.is_global(),
305            IpAddr::V6(ip) => ip.is_global(),
306        }
307    }
308
309    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
323    #[stable(feature = "ip_shared", since = "1.12.0")]
324    #[must_use]
325    #[inline]
326    pub const fn is_multicast(&self) -> bool {
327        match self {
328            IpAddr::V4(ip) => ip.is_multicast(),
329            IpAddr::V6(ip) => ip.is_multicast(),
330        }
331    }
332
333    #[unstable(feature = "ip", issue = "27709")]
352    #[must_use]
353    #[inline]
354    pub const fn is_documentation(&self) -> bool {
355        match self {
356            IpAddr::V4(ip) => ip.is_documentation(),
357            IpAddr::V6(ip) => ip.is_documentation(),
358        }
359    }
360
361    #[unstable(feature = "ip", issue = "27709")]
377    #[must_use]
378    #[inline]
379    pub const fn is_benchmarking(&self) -> bool {
380        match self {
381            IpAddr::V4(ip) => ip.is_benchmarking(),
382            IpAddr::V6(ip) => ip.is_benchmarking(),
383        }
384    }
385
386    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
400    #[stable(feature = "ipaddr_checker", since = "1.16.0")]
401    #[must_use]
402    #[inline]
403    pub const fn is_ipv4(&self) -> bool {
404        matches!(self, IpAddr::V4(_))
405    }
406
407    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
421    #[stable(feature = "ipaddr_checker", since = "1.16.0")]
422    #[must_use]
423    #[inline]
424    pub const fn is_ipv6(&self) -> bool {
425        matches!(self, IpAddr::V6(_))
426    }
427
428    #[inline]
445    #[must_use = "this returns the result of the operation, \
446                  without modifying the original"]
447    #[stable(feature = "ip_to_canonical", since = "1.75.0")]
448    #[rustc_const_stable(feature = "ip_to_canonical", since = "1.75.0")]
449    pub const fn to_canonical(&self) -> IpAddr {
450        match self {
451            IpAddr::V4(_) => *self,
452            IpAddr::V6(v6) => v6.to_canonical(),
453        }
454    }
455
456    #[unstable(feature = "ip_as_octets", issue = "137259")]
470    #[inline]
471    pub const fn as_octets(&self) -> &[u8] {
472        match self {
473            IpAddr::V4(ip) => ip.as_octets().as_slice(),
474            IpAddr::V6(ip) => ip.as_octets().as_slice(),
475        }
476    }
477}
478
479impl Ipv4Addr {
480    #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
492    #[stable(feature = "rust1", since = "1.0.0")]
493    #[must_use]
494    #[inline]
495    pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
496        Ipv4Addr { octets: [a, b, c, d] }
497    }
498
499    #[stable(feature = "ip_bits", since = "1.80.0")]
509    pub const BITS: u32 = 32;
510
511    #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
537    #[stable(feature = "ip_bits", since = "1.80.0")]
538    #[must_use]
539    #[inline]
540    pub const fn to_bits(self) -> u32 {
541        u32::from_be_bytes(self.octets)
542    }
543
544    #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
557    #[stable(feature = "ip_bits", since = "1.80.0")]
558    #[must_use]
559    #[inline]
560    pub const fn from_bits(bits: u32) -> Ipv4Addr {
561        Ipv4Addr { octets: bits.to_be_bytes() }
562    }
563
564    #[stable(feature = "ip_constructors", since = "1.30.0")]
575    pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
576
577    #[doc(alias = "INADDR_ANY")]
590    #[stable(feature = "ip_constructors", since = "1.30.0")]
591    pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
592
593    #[stable(feature = "ip_constructors", since = "1.30.0")]
604    pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255);
605
606    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
617    #[stable(feature = "rust1", since = "1.0.0")]
618    #[must_use]
619    #[inline]
620    pub const fn octets(&self) -> [u8; 4] {
621        self.octets
622    }
623
624    #[unstable(feature = "ip_from", issue = "131360")]
636    #[must_use]
637    #[inline]
638    pub const fn from_octets(octets: [u8; 4]) -> Ipv4Addr {
639        Ipv4Addr { octets }
640    }
641
642    #[unstable(feature = "ip_as_octets", issue = "137259")]
656    #[inline]
657    pub const fn as_octets(&self) -> &[u8; 4] {
658        &self.octets
659    }
660
661    #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
677    #[stable(feature = "ip_shared", since = "1.12.0")]
678    #[must_use]
679    #[inline]
680    pub const fn is_unspecified(&self) -> bool {
681        u32::from_be_bytes(self.octets) == 0
682    }
683
684    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
699    #[stable(since = "1.7.0", feature = "ip_17")]
700    #[must_use]
701    #[inline]
702    pub const fn is_loopback(&self) -> bool {
703        self.octets()[0] == 127
704    }
705
706    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
730    #[stable(since = "1.7.0", feature = "ip_17")]
731    #[must_use]
732    #[inline]
733    pub const fn is_private(&self) -> bool {
734        match self.octets() {
735            [10, ..] => true,
736            [172, b, ..] if b >= 16 && b <= 31 => true,
737            [192, 168, ..] => true,
738            _ => false,
739        }
740    }
741
742    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
758    #[stable(since = "1.7.0", feature = "ip_17")]
759    #[must_use]
760    #[inline]
761    pub const fn is_link_local(&self) -> bool {
762        matches!(self.octets(), [169, 254, ..])
763    }
764
765    #[unstable(feature = "ip", issue = "27709")]
837    #[must_use]
838    #[inline]
839    pub const fn is_global(&self) -> bool {
840        !(self.octets()[0] == 0 || self.is_private()
842            || self.is_shared()
843            || self.is_loopback()
844            || self.is_link_local()
845            || (
848                self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
849                && self.octets()[3] != 9 && self.octets()[3] != 10
850            )
851            || self.is_documentation()
852            || self.is_benchmarking()
853            || self.is_reserved()
854            || self.is_broadcast())
855    }
856
857    #[unstable(feature = "ip", issue = "27709")]
873    #[must_use]
874    #[inline]
875    pub const fn is_shared(&self) -> bool {
876        self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
877    }
878
879    #[unstable(feature = "ip", issue = "27709")]
900    #[must_use]
901    #[inline]
902    pub const fn is_benchmarking(&self) -> bool {
903        self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
904    }
905
906    #[unstable(feature = "ip", issue = "27709")]
936    #[must_use]
937    #[inline]
938    pub const fn is_reserved(&self) -> bool {
939        self.octets()[0] & 240 == 240 && !self.is_broadcast()
940    }
941
942    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
959    #[stable(since = "1.7.0", feature = "ip_17")]
960    #[must_use]
961    #[inline]
962    pub const fn is_multicast(&self) -> bool {
963        self.octets()[0] >= 224 && self.octets()[0] <= 239
964    }
965
966    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
981    #[stable(since = "1.7.0", feature = "ip_17")]
982    #[must_use]
983    #[inline]
984    pub const fn is_broadcast(&self) -> bool {
985        u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
986    }
987
988    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1009    #[stable(since = "1.7.0", feature = "ip_17")]
1010    #[must_use]
1011    #[inline]
1012    pub const fn is_documentation(&self) -> bool {
1013        matches!(self.octets(), [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _])
1014    }
1015
1016    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1037    #[stable(feature = "rust1", since = "1.0.0")]
1038    #[must_use = "this returns the result of the operation, \
1039                  without modifying the original"]
1040    #[inline]
1041    pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
1042        let [a, b, c, d] = self.octets();
1043        Ipv6Addr { octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] }
1044    }
1045
1046    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1062    #[stable(feature = "rust1", since = "1.0.0")]
1063    #[must_use = "this returns the result of the operation, \
1064                  without modifying the original"]
1065    #[inline]
1066    pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
1067        let [a, b, c, d] = self.octets();
1068        Ipv6Addr { octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] }
1069    }
1070}
1071
1072#[stable(feature = "ip_addr", since = "1.7.0")]
1073impl fmt::Display for IpAddr {
1074    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1075        match self {
1076            IpAddr::V4(ip) => ip.fmt(fmt),
1077            IpAddr::V6(ip) => ip.fmt(fmt),
1078        }
1079    }
1080}
1081
1082#[stable(feature = "ip_addr", since = "1.7.0")]
1083impl fmt::Debug for IpAddr {
1084    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1085        fmt::Display::fmt(self, fmt)
1086    }
1087}
1088
1089#[stable(feature = "ip_from_ip", since = "1.16.0")]
1090#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1091impl const From<Ipv4Addr> for IpAddr {
1092    #[inline]
1107    fn from(ipv4: Ipv4Addr) -> IpAddr {
1108        IpAddr::V4(ipv4)
1109    }
1110}
1111
1112#[stable(feature = "ip_from_ip", since = "1.16.0")]
1113#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1114impl const From<Ipv6Addr> for IpAddr {
1115    #[inline]
1130    fn from(ipv6: Ipv6Addr) -> IpAddr {
1131        IpAddr::V6(ipv6)
1132    }
1133}
1134
1135#[stable(feature = "rust1", since = "1.0.0")]
1136impl fmt::Display for Ipv4Addr {
1137    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1138        let octets = self.octets();
1139
1140        if fmt.precision().is_none() && fmt.width().is_none() {
1143            write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
1144        } else {
1145            const LONGEST_IPV4_ADDR: &str = "255.255.255.255";
1146
1147            let mut buf = DisplayBuffer::<{ LONGEST_IPV4_ADDR.len() }>::new();
1148            write!(buf, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
1150
1151            fmt.pad(buf.as_str())
1152        }
1153    }
1154}
1155
1156#[stable(feature = "rust1", since = "1.0.0")]
1157impl fmt::Debug for Ipv4Addr {
1158    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1159        fmt::Display::fmt(self, fmt)
1160    }
1161}
1162
1163#[stable(feature = "ip_cmp", since = "1.16.0")]
1164impl PartialEq<Ipv4Addr> for IpAddr {
1165    #[inline]
1166    fn eq(&self, other: &Ipv4Addr) -> bool {
1167        match self {
1168            IpAddr::V4(v4) => v4 == other,
1169            IpAddr::V6(_) => false,
1170        }
1171    }
1172}
1173
1174#[stable(feature = "ip_cmp", since = "1.16.0")]
1175impl PartialEq<IpAddr> for Ipv4Addr {
1176    #[inline]
1177    fn eq(&self, other: &IpAddr) -> bool {
1178        match other {
1179            IpAddr::V4(v4) => self == v4,
1180            IpAddr::V6(_) => false,
1181        }
1182    }
1183}
1184
1185#[stable(feature = "rust1", since = "1.0.0")]
1186impl PartialOrd for Ipv4Addr {
1187    #[inline]
1188    fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
1189        Some(self.cmp(other))
1190    }
1191}
1192
1193#[stable(feature = "ip_cmp", since = "1.16.0")]
1194impl PartialOrd<Ipv4Addr> for IpAddr {
1195    #[inline]
1196    fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
1197        match self {
1198            IpAddr::V4(v4) => v4.partial_cmp(other),
1199            IpAddr::V6(_) => Some(Ordering::Greater),
1200        }
1201    }
1202}
1203
1204#[stable(feature = "ip_cmp", since = "1.16.0")]
1205impl PartialOrd<IpAddr> for Ipv4Addr {
1206    #[inline]
1207    fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
1208        match other {
1209            IpAddr::V4(v4) => self.partial_cmp(v4),
1210            IpAddr::V6(_) => Some(Ordering::Less),
1211        }
1212    }
1213}
1214
1215#[stable(feature = "rust1", since = "1.0.0")]
1216impl Ord for Ipv4Addr {
1217    #[inline]
1218    fn cmp(&self, other: &Ipv4Addr) -> Ordering {
1219        self.octets.cmp(&other.octets)
1220    }
1221}
1222
1223#[stable(feature = "ip_u32", since = "1.1.0")]
1224#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1225impl const From<Ipv4Addr> for u32 {
1226    #[inline]
1228    fn from(ip: Ipv4Addr) -> u32 {
1229        ip.to_bits()
1230    }
1231}
1232
1233#[stable(feature = "ip_u32", since = "1.1.0")]
1234#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1235impl const From<u32> for Ipv4Addr {
1236    #[inline]
1238    fn from(ip: u32) -> Ipv4Addr {
1239        Ipv4Addr::from_bits(ip)
1240    }
1241}
1242
1243#[stable(feature = "from_slice_v4", since = "1.9.0")]
1244#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1245impl const From<[u8; 4]> for Ipv4Addr {
1246    #[inline]
1257    fn from(octets: [u8; 4]) -> Ipv4Addr {
1258        Ipv4Addr { octets }
1259    }
1260}
1261
1262#[stable(feature = "ip_from_slice", since = "1.17.0")]
1263#[rustc_const_unstable(feature = "const_try", issue = "74935")]
1264impl const From<[u8; 4]> for IpAddr {
1265    #[inline]
1276    fn from(octets: [u8; 4]) -> IpAddr {
1277        IpAddr::V4(Ipv4Addr::from(octets))
1278    }
1279}
1280
1281impl Ipv6Addr {
1282    #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
1294    #[stable(feature = "rust1", since = "1.0.0")]
1295    #[must_use]
1296    #[inline]
1297    pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
1298        let addr16 = [
1299            a.to_be(),
1300            b.to_be(),
1301            c.to_be(),
1302            d.to_be(),
1303            e.to_be(),
1304            f.to_be(),
1305            g.to_be(),
1306            h.to_be(),
1307        ];
1308        Ipv6Addr {
1309            octets: unsafe { transmute::<_, [u8; 16]>(addr16) },
1312        }
1313    }
1314
1315    #[stable(feature = "ip_bits", since = "1.80.0")]
1325    pub const BITS: u32 = 128;
1326
1327    #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
1364    #[stable(feature = "ip_bits", since = "1.80.0")]
1365    #[must_use]
1366    #[inline]
1367    pub const fn to_bits(self) -> u128 {
1368        u128::from_be_bytes(self.octets)
1369    }
1370
1371    #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
1389    #[stable(feature = "ip_bits", since = "1.80.0")]
1390    #[must_use]
1391    #[inline]
1392    pub const fn from_bits(bits: u128) -> Ipv6Addr {
1393        Ipv6Addr { octets: bits.to_be_bytes() }
1394    }
1395
1396    #[doc(alias = "IN6ADDR_LOOPBACK_INIT")]
1410    #[doc(alias = "in6addr_loopback")]
1411    #[stable(feature = "ip_constructors", since = "1.30.0")]
1412    pub const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
1413
1414    #[doc(alias = "IN6ADDR_ANY_INIT")]
1427    #[doc(alias = "in6addr_any")]
1428    #[stable(feature = "ip_constructors", since = "1.30.0")]
1429    pub const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
1430
1431    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1442    #[stable(feature = "rust1", since = "1.0.0")]
1443    #[must_use]
1444    #[inline]
1445    pub const fn segments(&self) -> [u16; 8] {
1446        let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.octets) };
1449        [
1451            u16::from_be(a),
1452            u16::from_be(b),
1453            u16::from_be(c),
1454            u16::from_be(d),
1455            u16::from_be(e),
1456            u16::from_be(f),
1457            u16::from_be(g),
1458            u16::from_be(h),
1459        ]
1460    }
1461
1462    #[unstable(feature = "ip_from", issue = "131360")]
1483    #[must_use]
1484    #[inline]
1485    pub const fn from_segments(segments: [u16; 8]) -> Ipv6Addr {
1486        let [a, b, c, d, e, f, g, h] = segments;
1487        Ipv6Addr::new(a, b, c, d, e, f, g, h)
1488    }
1489
1490    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1505    #[stable(since = "1.7.0", feature = "ip_17")]
1506    #[must_use]
1507    #[inline]
1508    pub const fn is_unspecified(&self) -> bool {
1509        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
1510    }
1511
1512    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1529    #[stable(since = "1.7.0", feature = "ip_17")]
1530    #[must_use]
1531    #[inline]
1532    pub const fn is_loopback(&self) -> bool {
1533        u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
1534    }
1535
1536    #[unstable(feature = "ip", issue = "27709")]
1602    #[must_use]
1603    #[inline]
1604    pub const fn is_global(&self) -> bool {
1605        !(self.is_unspecified()
1606            || self.is_loopback()
1607            || matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
1609            || matches!(self.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
1611            || matches!(self.segments(), [0x100, 0, 0, 0, _, _, _, _])
1613            || (matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
1615                && !(
1616                    u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
1618                    || u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
1620                    || matches!(self.segments(), [0x2001, 3, _, _, _, _, _, _])
1622                    || matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
1624                    || matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x3F)
1627                ))
1628            || matches!(self.segments(), [0x2002, _, _, _, _, _, _, _])
1631            || self.is_documentation()
1632            || matches!(self.segments(), [0x5f00, ..])
1634            || self.is_unique_local()
1635            || self.is_unicast_link_local())
1636    }
1637
1638    #[must_use]
1653    #[inline]
1654    #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1655    #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1656    pub const fn is_unique_local(&self) -> bool {
1657        (self.segments()[0] & 0xfe00) == 0xfc00
1658    }
1659
1660    #[unstable(feature = "ip", issue = "27709")]
1682    #[must_use]
1683    #[inline]
1684    pub const fn is_unicast(&self) -> bool {
1685        !self.is_multicast()
1686    }
1687
1688    #[must_use]
1731    #[inline]
1732    #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1733    #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1734    pub const fn is_unicast_link_local(&self) -> bool {
1735        (self.segments()[0] & 0xffc0) == 0xfe80
1736    }
1737
1738    #[unstable(feature = "ip", issue = "27709")]
1758    #[must_use]
1759    #[inline]
1760    pub const fn is_documentation(&self) -> bool {
1761        matches!(self.segments(), [0x2001, 0xdb8, ..] | [0x3fff, 0..=0x0fff, ..])
1762    }
1763
1764    #[unstable(feature = "ip", issue = "27709")]
1781    #[must_use]
1782    #[inline]
1783    pub const fn is_benchmarking(&self) -> bool {
1784        (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
1785    }
1786
1787    #[unstable(feature = "ip", issue = "27709")]
1818    #[must_use]
1819    #[inline]
1820    pub const fn is_unicast_global(&self) -> bool {
1821        self.is_unicast()
1822            && !self.is_loopback()
1823            && !self.is_unicast_link_local()
1824            && !self.is_unique_local()
1825            && !self.is_unspecified()
1826            && !self.is_documentation()
1827            && !self.is_benchmarking()
1828    }
1829
1830    #[unstable(feature = "ip", issue = "27709")]
1846    #[must_use]
1847    #[inline]
1848    pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
1849        if self.is_multicast() {
1850            match self.segments()[0] & 0x000f {
1851                1 => Some(Ipv6MulticastScope::InterfaceLocal),
1852                2 => Some(Ipv6MulticastScope::LinkLocal),
1853                3 => Some(Ipv6MulticastScope::RealmLocal),
1854                4 => Some(Ipv6MulticastScope::AdminLocal),
1855                5 => Some(Ipv6MulticastScope::SiteLocal),
1856                8 => Some(Ipv6MulticastScope::OrganizationLocal),
1857                14 => Some(Ipv6MulticastScope::Global),
1858                _ => None,
1859            }
1860        } else {
1861            None
1862        }
1863    }
1864
1865    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1880    #[stable(since = "1.7.0", feature = "ip_17")]
1881    #[must_use]
1882    #[inline]
1883    pub const fn is_multicast(&self) -> bool {
1884        (self.segments()[0] & 0xff00) == 0xff00
1885    }
1886
1887    #[unstable(feature = "ip", issue = "27709")]
1905    #[must_use]
1906    #[inline]
1907    pub const fn is_ipv4_mapped(&self) -> bool {
1908        matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
1909    }
1910
1911    #[inline]
1932    #[must_use = "this returns the result of the operation, \
1933                  without modifying the original"]
1934    #[stable(feature = "ipv6_to_ipv4_mapped", since = "1.63.0")]
1935    #[rustc_const_stable(feature = "const_ipv6_to_ipv4_mapped", since = "1.75.0")]
1936    pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
1937        match self.octets() {
1938            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
1939                Some(Ipv4Addr::new(a, b, c, d))
1940            }
1941            _ => None,
1942        }
1943    }
1944
1945    #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1974    #[stable(feature = "rust1", since = "1.0.0")]
1975    #[must_use = "this returns the result of the operation, \
1976                  without modifying the original"]
1977    #[inline]
1978    pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
1979        if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
1980            let [a, b] = ab.to_be_bytes();
1981            let [c, d] = cd.to_be_bytes();
1982            Some(Ipv4Addr::new(a, b, c, d))
1983        } else {
1984            None
1985        }
1986    }
1987
1988    #[inline]
2000    #[must_use = "this returns the result of the operation, \
2001                  without modifying the original"]
2002    #[stable(feature = "ip_to_canonical", since = "1.75.0")]
2003    #[rustc_const_stable(feature = "ip_to_canonical", since = "1.75.0")]
2004    pub const fn to_canonical(&self) -> IpAddr {
2005        if let Some(mapped) = self.to_ipv4_mapped() {
2006            return IpAddr::V4(mapped);
2007        }
2008        IpAddr::V6(*self)
2009    }
2010
2011    #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
2020    #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
2021    #[must_use]
2022    #[inline]
2023    pub const fn octets(&self) -> [u8; 16] {
2024        self.octets
2025    }
2026
2027    #[unstable(feature = "ip_from", issue = "131360")]
2048    #[must_use]
2049    #[inline]
2050    pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr {
2051        Ipv6Addr { octets }
2052    }
2053
2054    #[unstable(feature = "ip_as_octets", issue = "137259")]
2068    #[inline]
2069    pub const fn as_octets(&self) -> &[u8; 16] {
2070        &self.octets
2071    }
2072}
2073
2074#[stable(feature = "rust1", since = "1.0.0")]
2077impl fmt::Display for Ipv6Addr {
2078    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2079        if f.precision().is_none() && f.width().is_none() {
2082            let segments = self.segments();
2083
2084            if let Some(ipv4) = self.to_ipv4_mapped() {
2085                write!(f, "::ffff:{}", ipv4)
2086            } else {
2087                #[derive(Copy, Clone, Default)]
2088                struct Span {
2089                    start: usize,
2090                    len: usize,
2091                }
2092
2093                let zeroes = {
2095                    let mut longest = Span::default();
2096                    let mut current = Span::default();
2097
2098                    for (i, &segment) in segments.iter().enumerate() {
2099                        if segment == 0 {
2100                            if current.len == 0 {
2101                                current.start = i;
2102                            }
2103
2104                            current.len += 1;
2105
2106                            if current.len > longest.len {
2107                                longest = current;
2108                            }
2109                        } else {
2110                            current = Span::default();
2111                        }
2112                    }
2113
2114                    longest
2115                };
2116
2117                #[inline]
2119                fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) -> fmt::Result {
2120                    if let Some((first, tail)) = chunk.split_first() {
2121                        write!(f, "{:x}", first)?;
2122                        for segment in tail {
2123                            f.write_char(':')?;
2124                            write!(f, "{:x}", segment)?;
2125                        }
2126                    }
2127                    Ok(())
2128                }
2129
2130                if zeroes.len > 1 {
2131                    fmt_subslice(f, &segments[..zeroes.start])?;
2132                    f.write_str("::")?;
2133                    fmt_subslice(f, &segments[zeroes.start + zeroes.len..])
2134                } else {
2135                    fmt_subslice(f, &segments)
2136                }
2137            }
2138        } else {
2139            const LONGEST_IPV6_ADDR: &str = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
2140
2141            let mut buf = DisplayBuffer::<{ LONGEST_IPV6_ADDR.len() }>::new();
2142            write!(buf, "{}", self).unwrap();
2144
2145            f.pad(buf.as_str())
2146        }
2147    }
2148}
2149
2150#[stable(feature = "rust1", since = "1.0.0")]
2151impl fmt::Debug for Ipv6Addr {
2152    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2153        fmt::Display::fmt(self, fmt)
2154    }
2155}
2156
2157#[stable(feature = "ip_cmp", since = "1.16.0")]
2158impl PartialEq<IpAddr> for Ipv6Addr {
2159    #[inline]
2160    fn eq(&self, other: &IpAddr) -> bool {
2161        match other {
2162            IpAddr::V4(_) => false,
2163            IpAddr::V6(v6) => self == v6,
2164        }
2165    }
2166}
2167
2168#[stable(feature = "ip_cmp", since = "1.16.0")]
2169impl PartialEq<Ipv6Addr> for IpAddr {
2170    #[inline]
2171    fn eq(&self, other: &Ipv6Addr) -> bool {
2172        match self {
2173            IpAddr::V4(_) => false,
2174            IpAddr::V6(v6) => v6 == other,
2175        }
2176    }
2177}
2178
2179#[stable(feature = "rust1", since = "1.0.0")]
2180impl PartialOrd for Ipv6Addr {
2181    #[inline]
2182    fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
2183        Some(self.cmp(other))
2184    }
2185}
2186
2187#[stable(feature = "ip_cmp", since = "1.16.0")]
2188impl PartialOrd<Ipv6Addr> for IpAddr {
2189    #[inline]
2190    fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
2191        match self {
2192            IpAddr::V4(_) => Some(Ordering::Less),
2193            IpAddr::V6(v6) => v6.partial_cmp(other),
2194        }
2195    }
2196}
2197
2198#[stable(feature = "ip_cmp", since = "1.16.0")]
2199impl PartialOrd<IpAddr> for Ipv6Addr {
2200    #[inline]
2201    fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
2202        match other {
2203            IpAddr::V4(_) => Some(Ordering::Greater),
2204            IpAddr::V6(v6) => self.partial_cmp(v6),
2205        }
2206    }
2207}
2208
2209#[stable(feature = "rust1", since = "1.0.0")]
2210impl Ord for Ipv6Addr {
2211    #[inline]
2212    fn cmp(&self, other: &Ipv6Addr) -> Ordering {
2213        self.segments().cmp(&other.segments())
2214    }
2215}
2216
2217#[stable(feature = "i128", since = "1.26.0")]
2218#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2219impl const From<Ipv6Addr> for u128 {
2220    #[inline]
2222    fn from(ip: Ipv6Addr) -> u128 {
2223        ip.to_bits()
2224    }
2225}
2226#[stable(feature = "i128", since = "1.26.0")]
2227#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2228impl const From<u128> for Ipv6Addr {
2229    #[inline]
2231    fn from(ip: u128) -> Ipv6Addr {
2232        Ipv6Addr::from_bits(ip)
2233    }
2234}
2235
2236#[stable(feature = "ipv6_from_octets", since = "1.9.0")]
2237#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2238impl const From<[u8; 16]> for Ipv6Addr {
2239    #[inline]
2259    fn from(octets: [u8; 16]) -> Ipv6Addr {
2260        Ipv6Addr { octets }
2261    }
2262}
2263
2264#[stable(feature = "ipv6_from_segments", since = "1.16.0")]
2265#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2266impl const From<[u16; 8]> for Ipv6Addr {
2267    #[inline]
2287    fn from(segments: [u16; 8]) -> Ipv6Addr {
2288        let [a, b, c, d, e, f, g, h] = segments;
2289        Ipv6Addr::new(a, b, c, d, e, f, g, h)
2290    }
2291}
2292
2293#[stable(feature = "ip_from_slice", since = "1.17.0")]
2294#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2295impl const From<[u8; 16]> for IpAddr {
2296    #[inline]
2316    fn from(octets: [u8; 16]) -> IpAddr {
2317        IpAddr::V6(Ipv6Addr::from(octets))
2318    }
2319}
2320
2321#[stable(feature = "ip_from_slice", since = "1.17.0")]
2322#[rustc_const_unstable(feature = "const_try", issue = "74935")]
2323impl const From<[u16; 8]> for IpAddr {
2324    #[inline]
2344    fn from(segments: [u16; 8]) -> IpAddr {
2345        IpAddr::V6(Ipv6Addr::from(segments))
2346    }
2347}
2348
2349#[stable(feature = "ip_bitops", since = "1.75.0")]
2350#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2351impl const Not for Ipv4Addr {
2352    type Output = Ipv4Addr;
2353
2354    #[inline]
2355    fn not(mut self) -> Ipv4Addr {
2356        let mut idx = 0;
2357        while idx < 4 {
2358            self.octets[idx] = !self.octets[idx];
2359            idx += 1;
2360        }
2361        self
2362    }
2363}
2364
2365#[stable(feature = "ip_bitops", since = "1.75.0")]
2366#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2367impl const Not for &'_ Ipv4Addr {
2368    type Output = Ipv4Addr;
2369
2370    #[inline]
2371    fn not(self) -> Ipv4Addr {
2372        !*self
2373    }
2374}
2375
2376#[stable(feature = "ip_bitops", since = "1.75.0")]
2377#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2378impl const Not for Ipv6Addr {
2379    type Output = Ipv6Addr;
2380
2381    #[inline]
2382    fn not(mut self) -> Ipv6Addr {
2383        let mut idx = 0;
2384        while idx < 16 {
2385            self.octets[idx] = !self.octets[idx];
2386            idx += 1;
2387        }
2388        self
2389    }
2390}
2391
2392#[stable(feature = "ip_bitops", since = "1.75.0")]
2393#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2394impl const Not for &'_ Ipv6Addr {
2395    type Output = Ipv6Addr;
2396
2397    #[inline]
2398    fn not(self) -> Ipv6Addr {
2399        !*self
2400    }
2401}
2402
2403macro_rules! bitop_impls {
2404    ($(
2405        $(#[$attr:meta])*
2406        impl ($BitOp:ident, $BitOpAssign:ident) for $ty:ty = ($bitop:ident, $bitop_assign:ident);
2407    )*) => {
2408        $(
2409            $(#[$attr])*
2410            impl const $BitOpAssign for $ty {
2411                fn $bitop_assign(&mut self, rhs: $ty) {
2412                    let mut idx = 0;
2413                    while idx < self.octets.len() {
2414                        self.octets[idx].$bitop_assign(rhs.octets[idx]);
2415                        idx += 1;
2416                    }
2417                }
2418            }
2419
2420            $(#[$attr])*
2421            impl const $BitOpAssign<&'_ $ty> for $ty {
2422                fn $bitop_assign(&mut self, rhs: &'_ $ty) {
2423                    self.$bitop_assign(*rhs);
2424                }
2425            }
2426
2427            $(#[$attr])*
2428            impl const $BitOp for $ty {
2429                type Output = $ty;
2430
2431                #[inline]
2432                fn $bitop(mut self, rhs: $ty) -> $ty {
2433                    self.$bitop_assign(rhs);
2434                    self
2435                }
2436            }
2437
2438            $(#[$attr])*
2439            impl const $BitOp<&'_ $ty> for $ty {
2440                type Output = $ty;
2441
2442                #[inline]
2443                fn $bitop(mut self, rhs: &'_ $ty) -> $ty {
2444                    self.$bitop_assign(*rhs);
2445                    self
2446                }
2447            }
2448
2449            $(#[$attr])*
2450            impl const $BitOp<$ty> for &'_ $ty {
2451                type Output = $ty;
2452
2453                #[inline]
2454                fn $bitop(self, rhs: $ty) -> $ty {
2455                    let mut lhs = *self;
2456                    lhs.$bitop_assign(rhs);
2457                    lhs
2458                }
2459            }
2460
2461            $(#[$attr])*
2462            impl const $BitOp<&'_ $ty> for &'_ $ty {
2463                type Output = $ty;
2464
2465                #[inline]
2466                fn $bitop(self, rhs: &'_ $ty) -> $ty {
2467                    let mut lhs = *self;
2468                    lhs.$bitop_assign(*rhs);
2469                    lhs
2470                }
2471            }
2472        )*
2473    };
2474}
2475
2476bitop_impls! {
2477    #[stable(feature = "ip_bitops", since = "1.75.0")]
2478    #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2479    impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign);
2480    #[stable(feature = "ip_bitops", since = "1.75.0")]
2481    #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2482    impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign);
2483
2484    #[stable(feature = "ip_bitops", since = "1.75.0")]
2485    #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2486    impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign);
2487    #[stable(feature = "ip_bitops", since = "1.75.0")]
2488    #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2489    impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign);
2490}

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4