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(#[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::marker::Copy for IpAddr { }Copy, #[automatically_derived]
#[doc(hidden)]
#[stable(feature = "ip_addr", since = "1.7.0")]
unsafe impl crate::clone::TrivialClone for IpAddr { }
#[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::clone::Clone for IpAddr {
#[inline]
fn clone(&self) -> IpAddr {
let _: crate::clone::AssertParamIsClone<Ipv4Addr>;
let _: crate::clone::AssertParamIsClone<Ipv6Addr>;
*self
}
}Clone, #[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::cmp::Eq for IpAddr {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<Ipv4Addr>;
let _: crate::cmp::AssertParamIsEq<Ipv6Addr>;
}
}Eq, #[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::marker::StructuralPartialEq for IpAddr { }
#[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::cmp::PartialEq for IpAddr {
#[inline]
fn eq(&self, other: &IpAddr) -> bool {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(IpAddr::V4(__self_0), IpAddr::V4(__arg1_0)) =>
__self_0 == __arg1_0,
(IpAddr::V6(__self_0), IpAddr::V6(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { crate::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::hash::Hash for IpAddr {
#[inline]
fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = crate::intrinsics::discriminant_value(self);
crate::hash::Hash::hash(&__self_discr, state);
match self {
IpAddr::V4(__self_0) => crate::hash::Hash::hash(__self_0, state),
IpAddr::V6(__self_0) => crate::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::cmp::PartialOrd for IpAddr {
#[inline]
fn partial_cmp(&self, other: &IpAddr)
-> crate::option::Option<crate::cmp::Ordering> {
crate::option::Option::Some(crate::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
#[stable(feature = "ip_addr", since = "1.7.0")]
impl crate::cmp::Ord for IpAddr {
#[inline]
fn cmp(&self, other: &IpAddr) -> crate::cmp::Ordering {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
match crate::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
crate::cmp::Ordering::Equal =>
match (self, other) {
(IpAddr::V4(__self_0), IpAddr::V4(__arg1_0)) =>
crate::cmp::Ord::cmp(__self_0, __arg1_0),
(IpAddr::V6(__self_0), IpAddr::V6(__arg1_0)) =>
crate::cmp::Ord::cmp(__self_0, __arg1_0),
_ => unsafe { crate::intrinsics::unreachable() }
},
cmp => cmp,
}
}
}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(#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::Copy for Ipv4Addr { }Copy)]
72#[derive_const(#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[doc(hidden)]
#[stable(feature = "rust1", since = "1.0.0")]
const unsafe impl crate::clone::TrivialClone for Ipv4Addr { }
#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::clone::Clone for Ipv4Addr {
#[inline]
fn clone(&self) -> Ipv4Addr {
let _: crate::clone::AssertParamIsClone<[u8; 4]>;
*self
}
}Clone, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::StructuralPartialEq for Ipv4Addr { }
#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::cmp::PartialEq for Ipv4Addr {
#[inline]
fn eq(&self, other: &Ipv4Addr) -> bool { self.octets == other.octets }
}PartialEq, #[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::cmp::Eq for Ipv4Addr {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<[u8; 4]>;
}
}Eq)]
73#[stable(feature = "rust1", since = "1.0.0")]
74pub struct Ipv4Addr {
75 octets: [u8; 4],
76}
77
78#[stable(feature = "rust1", since = "1.0.0")]
79impl Hash for Ipv4Addr {
80 fn hash<H: Hasher>(&self, state: &mut H) {
81 u32::from_ne_bytes(self.octets).hash(state);
85 }
86}
87
88#[rustc_diagnostic_item = "Ipv6Addr"]
165#[derive(#[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::Copy for Ipv6Addr { }Copy)]
166#[derive_const(#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[doc(hidden)]
#[stable(feature = "rust1", since = "1.0.0")]
const unsafe impl crate::clone::TrivialClone for Ipv6Addr { }
#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::clone::Clone for Ipv6Addr {
#[inline]
fn clone(&self) -> Ipv6Addr {
let _: crate::clone::AssertParamIsClone<[u8; 16]>;
*self
}
}Clone, #[automatically_derived]
#[stable(feature = "rust1", since = "1.0.0")]
impl crate::marker::StructuralPartialEq for Ipv6Addr { }
#[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::cmp::PartialEq for Ipv6Addr {
#[inline]
fn eq(&self, other: &Ipv6Addr) -> bool { self.octets == other.octets }
}PartialEq, #[automatically_derived]
#[rustc_const_unstable(feature = "derive_const", issue = "118304")]
#[stable(feature = "rust1", since = "1.0.0")]
const impl crate::cmp::Eq for Ipv6Addr {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: crate::cmp::AssertParamIsEq<[u8; 16]>;
}
}Eq)]
167#[stable(feature = "rust1", since = "1.0.0")]
168pub struct Ipv6Addr {
169 octets: [u8; 16],
170}
171
172#[stable(feature = "rust1", since = "1.0.0")]
173impl Hash for Ipv6Addr {
174 fn hash<H: Hasher>(&self, state: &mut H) {
175 u128::from_ne_bytes(self.octets).hash(state);
179 }
180}
181
182#[derive(#[automatically_derived]
#[doc(hidden)]
#[unstable(feature = "ip", issue = "27709")]
unsafe impl crate::clone::TrivialClone for Ipv6MulticastScope { }
#[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::clone::Clone for Ipv6MulticastScope {
#[inline]
fn clone(&self) -> Ipv6MulticastScope { *self }
}Clone, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::marker::Copy for Ipv6MulticastScope { }Copy, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::fmt::Debug for Ipv6MulticastScope {
#[inline]
fn fmt(&self, f: &mut crate::fmt::Formatter) -> crate::fmt::Result {
crate::fmt::Formatter::write_str(f,
match self {
Ipv6MulticastScope::Reserved0 => "Reserved0",
Ipv6MulticastScope::InterfaceLocal => "InterfaceLocal",
Ipv6MulticastScope::LinkLocal => "LinkLocal",
Ipv6MulticastScope::RealmLocal => "RealmLocal",
Ipv6MulticastScope::AdminLocal => "AdminLocal",
Ipv6MulticastScope::SiteLocal => "SiteLocal",
Ipv6MulticastScope::Unassigned6 => "Unassigned6",
Ipv6MulticastScope::Unassigned7 => "Unassigned7",
Ipv6MulticastScope::OrganizationLocal => "OrganizationLocal",
Ipv6MulticastScope::Unassigned9 => "Unassigned9",
Ipv6MulticastScope::UnassignedA => "UnassignedA",
Ipv6MulticastScope::UnassignedB => "UnassignedB",
Ipv6MulticastScope::UnassignedC => "UnassignedC",
Ipv6MulticastScope::UnassignedD => "UnassignedD",
Ipv6MulticastScope::Global => "Global",
Ipv6MulticastScope::ReservedF => "ReservedF",
})
}
}Debug, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::marker::StructuralPartialEq for Ipv6MulticastScope { }
#[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::cmp::PartialEq for Ipv6MulticastScope {
#[inline]
fn eq(&self, other: &Ipv6MulticastScope) -> bool {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::cmp::Eq for Ipv6MulticastScope {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::cmp::PartialOrd for Ipv6MulticastScope {
#[inline]
fn partial_cmp(&self, other: &Ipv6MulticastScope)
-> crate::option::Option<crate::cmp::Ordering> {
crate::option::Option::Some(crate::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::cmp::Ord for Ipv6MulticastScope {
#[inline]
fn cmp(&self, other: &Ipv6MulticastScope) -> crate::cmp::Ordering {
let __self_discr = crate::intrinsics::discriminant_value(self);
let __arg1_discr = crate::intrinsics::discriminant_value(other);
crate::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
#[unstable(feature = "ip", issue = "27709")]
impl crate::hash::Hash for Ipv6MulticastScope {
#[inline]
fn hash<__H: crate::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = crate::intrinsics::discriminant_value(self);
crate::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
227#[unstable(feature = "ip", issue = "27709")]
228pub enum Ipv6MulticastScope {
229 #[doc(hidden)]
231 #[unstable(
232 feature = "ip_multicast_reserved",
233 reason = "not yet assigned by IETF",
234 issue = "none"
235 )]
236 Reserved0 = 0x0,
237 InterfaceLocal = 0x1,
239 LinkLocal = 0x2,
241 RealmLocal = 0x3,
243 AdminLocal = 0x4,
245 SiteLocal = 0x5,
247
248 Unassigned6 = 0x6,
251 Unassigned7 = 0x7,
254 OrganizationLocal = 0x8,
256 Unassigned9 = 0x9,
259 UnassignedA = 0xA,
262 UnassignedB = 0xB,
265 UnassignedC = 0xC,
268 UnassignedD = 0xD,
271 Global = 0xE,
273 #[doc(hidden)]
275 #[unstable(
276 feature = "ip_multicast_reserved",
277 reason = "not yet assigned by IETF",
278 issue = "none"
279 )]
280 ReservedF = 0xF,
281}
282
283impl IpAddr {
284 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
298 #[stable(feature = "ip_shared", since = "1.12.0")]
299 #[must_use]
300 #[inline]
301 pub const fn is_unspecified(&self) -> bool {
302 match self {
303 IpAddr::V4(ip) => ip.is_unspecified(),
304 IpAddr::V6(ip) => ip.is_unspecified(),
305 }
306 }
307
308 #[inline]
328 #[must_use]
329 #[unstable(feature = "addr_unspecified_from", issue = "158975")]
330 pub const fn unspecified_from(this: Self) -> Self {
331 match this {
332 Self::V4(_) => Self::V4(Ipv4Addr::UNSPECIFIED),
333 Self::V6(_) => Self::V6(Ipv6Addr::UNSPECIFIED),
334 }
335 }
336
337 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
351 #[stable(feature = "ip_shared", since = "1.12.0")]
352 #[must_use]
353 #[inline]
354 pub const fn is_loopback(&self) -> bool {
355 match self {
356 IpAddr::V4(ip) => ip.is_loopback(),
357 IpAddr::V6(ip) => ip.is_loopback(),
358 }
359 }
360
361 #[unstable(feature = "ip", issue = "27709")]
377 #[must_use]
378 #[inline]
379 pub const fn is_global(&self) -> bool {
380 match self {
381 IpAddr::V4(ip) => ip.is_global(),
382 IpAddr::V6(ip) => ip.is_global(),
383 }
384 }
385
386 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
400 #[stable(feature = "ip_shared", since = "1.12.0")]
401 #[must_use]
402 #[inline]
403 pub const fn is_multicast(&self) -> bool {
404 match self {
405 IpAddr::V4(ip) => ip.is_multicast(),
406 IpAddr::V6(ip) => ip.is_multicast(),
407 }
408 }
409
410 #[unstable(feature = "ip", issue = "27709")]
429 #[must_use]
430 #[inline]
431 pub const fn is_documentation(&self) -> bool {
432 match self {
433 IpAddr::V4(ip) => ip.is_documentation(),
434 IpAddr::V6(ip) => ip.is_documentation(),
435 }
436 }
437
438 #[unstable(feature = "ip", issue = "27709")]
454 #[must_use]
455 #[inline]
456 pub const fn is_benchmarking(&self) -> bool {
457 match self {
458 IpAddr::V4(ip) => ip.is_benchmarking(),
459 IpAddr::V6(ip) => ip.is_benchmarking(),
460 }
461 }
462
463 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
477 #[stable(feature = "ipaddr_checker", since = "1.16.0")]
478 #[must_use]
479 #[inline]
480 pub const fn is_ipv4(&self) -> bool {
481 #[allow(non_exhaustive_omitted_patterns)] match self {
IpAddr::V4(_) => true,
_ => false,
}matches!(self, IpAddr::V4(_))
482 }
483
484 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
498 #[stable(feature = "ipaddr_checker", since = "1.16.0")]
499 #[must_use]
500 #[inline]
501 pub const fn is_ipv6(&self) -> bool {
502 #[allow(non_exhaustive_omitted_patterns)] match self {
IpAddr::V6(_) => true,
_ => false,
}matches!(self, IpAddr::V6(_))
503 }
504
505 #[inline]
522 #[must_use = "this returns the result of the operation, \
523 without modifying the original"]
524 #[stable(feature = "ip_to_canonical", since = "1.75.0")]
525 #[rustc_const_stable(feature = "ip_to_canonical", since = "1.75.0")]
526 pub const fn to_canonical(&self) -> IpAddr {
527 match self {
528 IpAddr::V4(_) => *self,
529 IpAddr::V6(v6) => v6.to_canonical(),
530 }
531 }
532
533 #[unstable(feature = "ip_as_octets", issue = "137259")]
547 #[inline]
548 pub const fn as_octets(&self) -> &[u8] {
549 match self {
550 IpAddr::V4(ip) => ip.as_octets().as_slice(),
551 IpAddr::V6(ip) => ip.as_octets().as_slice(),
552 }
553 }
554}
555
556impl Ipv4Addr {
557 #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
569 #[stable(feature = "rust1", since = "1.0.0")]
570 #[must_use]
571 #[inline]
572 pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
573 Ipv4Addr { octets: [a, b, c, d] }
574 }
575
576 #[stable(feature = "ip_bits", since = "1.80.0")]
586 pub const BITS: u32 = 32;
587
588 #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
614 #[stable(feature = "ip_bits", since = "1.80.0")]
615 #[must_use]
616 #[inline]
617 pub const fn to_bits(self) -> u32 {
618 u32::from_be_bytes(self.octets)
619 }
620
621 #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
634 #[stable(feature = "ip_bits", since = "1.80.0")]
635 #[must_use]
636 #[inline]
637 pub const fn from_bits(bits: u32) -> Ipv4Addr {
638 Ipv4Addr { octets: bits.to_be_bytes() }
639 }
640
641 #[stable(feature = "ip_constructors", since = "1.30.0")]
652 pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1);
653
654 #[doc(alias = "INADDR_ANY")]
667 #[stable(feature = "ip_constructors", since = "1.30.0")]
668 pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0);
669
670 #[stable(feature = "ip_constructors", since = "1.30.0")]
681 pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255);
682
683 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
694 #[stable(feature = "rust1", since = "1.0.0")]
695 #[must_use]
696 #[inline]
697 pub const fn octets(&self) -> [u8; 4] {
698 self.octets
699 }
700
701 #[stable(feature = "ip_from", since = "1.91.0")]
712 #[rustc_const_stable(feature = "ip_from", since = "1.91.0")]
713 #[must_use]
714 #[inline]
715 pub const fn from_octets(octets: [u8; 4]) -> Ipv4Addr {
716 Ipv4Addr { octets }
717 }
718
719 #[unstable(feature = "ip_as_octets", issue = "137259")]
733 #[inline]
734 pub const fn as_octets(&self) -> &[u8; 4] {
735 &self.octets
736 }
737
738 #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
754 #[stable(feature = "ip_shared", since = "1.12.0")]
755 #[must_use]
756 #[inline]
757 pub const fn is_unspecified(&self) -> bool {
758 u32::from_be_bytes(self.octets) == 0
759 }
760
761 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
776 #[stable(since = "1.7.0", feature = "ip_17")]
777 #[must_use]
778 #[inline]
779 pub const fn is_loopback(&self) -> bool {
780 self.octets()[0] == 127
781 }
782
783 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
807 #[stable(since = "1.7.0", feature = "ip_17")]
808 #[must_use]
809 #[inline]
810 pub const fn is_private(&self) -> bool {
811 match self.octets() {
812 [10, ..] => true,
813 [172, b, ..] if b >= 16 && b <= 31 => true,
814 [192, 168, ..] => true,
815 _ => false,
816 }
817 }
818
819 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
835 #[stable(since = "1.7.0", feature = "ip_17")]
836 #[must_use]
837 #[inline]
838 pub const fn is_link_local(&self) -> bool {
839 #[allow(non_exhaustive_omitted_patterns)] match self.octets() {
[169, 254, ..] => true,
_ => false,
}matches!(self.octets(), [169, 254, ..])
840 }
841
842 #[unstable(feature = "ip", issue = "27709")]
914 #[must_use]
915 #[inline]
916 pub const fn is_global(&self) -> bool {
917 !(self.octets()[0] == 0 || self.is_private()
919 || self.is_shared()
920 || self.is_loopback()
921 || self.is_link_local()
922 || (
925 self.octets()[0] == 192 && self.octets()[1] == 0 && self.octets()[2] == 0
926 && self.octets()[3] != 9 && self.octets()[3] != 10
927 )
928 || self.is_documentation()
929 || self.is_benchmarking()
930 || self.is_reserved()
931 || self.is_broadcast())
932 }
933
934 #[unstable(feature = "ip", issue = "27709")]
950 #[must_use]
951 #[inline]
952 pub const fn is_shared(&self) -> bool {
953 self.octets()[0] == 100 && (self.octets()[1] & 0b1100_0000 == 0b0100_0000)
954 }
955
956 #[unstable(feature = "ip", issue = "27709")]
977 #[must_use]
978 #[inline]
979 pub const fn is_benchmarking(&self) -> bool {
980 self.octets()[0] == 198 && (self.octets()[1] & 0xfe) == 18
981 }
982
983 #[unstable(feature = "ip", issue = "27709")]
1013 #[must_use]
1014 #[inline]
1015 pub const fn is_reserved(&self) -> bool {
1016 self.octets()[0] & 240 == 240 && !self.is_broadcast()
1017 }
1018
1019 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1036 #[stable(since = "1.7.0", feature = "ip_17")]
1037 #[must_use]
1038 #[inline]
1039 pub const fn is_multicast(&self) -> bool {
1040 self.octets()[0] >= 224 && self.octets()[0] <= 239
1041 }
1042
1043 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1058 #[stable(since = "1.7.0", feature = "ip_17")]
1059 #[must_use]
1060 #[inline]
1061 pub const fn is_broadcast(&self) -> bool {
1062 u32::from_be_bytes(self.octets()) == u32::from_be_bytes(Self::BROADCAST.octets())
1063 }
1064
1065 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1086 #[stable(since = "1.7.0", feature = "ip_17")]
1087 #[must_use]
1088 #[inline]
1089 pub const fn is_documentation(&self) -> bool {
1090 #[allow(non_exhaustive_omitted_patterns)] match self.octets() {
[192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _] => true,
_ => false,
}matches!(self.octets(), [192, 0, 2, _] | [198, 51, 100, _] | [203, 0, 113, _])
1091 }
1092
1093 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1114 #[stable(feature = "rust1", since = "1.0.0")]
1115 #[must_use = "this returns the result of the operation, \
1116 without modifying the original"]
1117 #[inline]
1118 pub const fn to_ipv6_compatible(&self) -> Ipv6Addr {
1119 let [a, b, c, d] = self.octets();
1120 Ipv6Addr { octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] }
1121 }
1122
1123 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1139 #[stable(feature = "rust1", since = "1.0.0")]
1140 #[must_use = "this returns the result of the operation, \
1141 without modifying the original"]
1142 #[inline]
1143 pub const fn to_ipv6_mapped(&self) -> Ipv6Addr {
1144 let [a, b, c, d] = self.octets();
1145 Ipv6Addr { octets: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] }
1146 }
1147}
1148
1149#[stable(feature = "ip_addr", since = "1.7.0")]
1150impl fmt::Display for IpAddr {
1151 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1152 match self {
1153 IpAddr::V4(ip) => ip.fmt(fmt),
1154 IpAddr::V6(ip) => ip.fmt(fmt),
1155 }
1156 }
1157}
1158
1159#[stable(feature = "ip_addr", since = "1.7.0")]
1160impl fmt::Debug for IpAddr {
1161 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1162 fmt::Display::fmt(self, fmt)
1163 }
1164}
1165
1166#[stable(feature = "ip_from_ip", since = "1.16.0")]
1167#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1168const impl From<Ipv4Addr> for IpAddr {
1169 #[inline]
1184 fn from(ipv4: Ipv4Addr) -> IpAddr {
1185 IpAddr::V4(ipv4)
1186 }
1187}
1188
1189#[stable(feature = "ip_from_ip", since = "1.16.0")]
1190#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1191const impl From<Ipv6Addr> for IpAddr {
1192 #[inline]
1207 fn from(ipv6: Ipv6Addr) -> IpAddr {
1208 IpAddr::V6(ipv6)
1209 }
1210}
1211
1212#[stable(feature = "rust1", since = "1.0.0")]
1213impl fmt::Display for Ipv4Addr {
1214 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1215 let octets = self.octets();
1216
1217 if fmt.precision().is_none() && fmt.width().is_none() {
1220 fmt.write_fmt(format_args!("{0}.{1}.{2}.{3}", octets[0], octets[1], octets[2],
octets[3]))write!(fmt, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3])
1221 } else {
1222 const LONGEST_IPV4_ADDR: &str = "255.255.255.255";
1223
1224 let mut buf = DisplayBuffer::buffer::<{ LONGEST_IPV4_ADDR.len() }>();
1225 let mut buf = DisplayBuffer::new(&mut buf);
1226 buf.write_fmt(format_args!("{0}.{1}.{2}.{3}", octets[0], octets[1], octets[2],
octets[3]))write!(buf, "{}.{}.{}.{}", octets[0], octets[1], octets[2], octets[3]).unwrap();
1228
1229 fmt.pad(buf.as_str())
1230 }
1231 }
1232}
1233
1234#[stable(feature = "rust1", since = "1.0.0")]
1235impl fmt::Debug for Ipv4Addr {
1236 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1237 fmt::Display::fmt(self, fmt)
1238 }
1239}
1240
1241#[stable(feature = "ip_cmp", since = "1.16.0")]
1242impl PartialEq<Ipv4Addr> for IpAddr {
1243 #[inline]
1244 fn eq(&self, other: &Ipv4Addr) -> bool {
1245 match self {
1246 IpAddr::V4(v4) => v4 == other,
1247 IpAddr::V6(_) => false,
1248 }
1249 }
1250}
1251
1252#[stable(feature = "ip_cmp", since = "1.16.0")]
1253impl PartialEq<IpAddr> for Ipv4Addr {
1254 #[inline]
1255 fn eq(&self, other: &IpAddr) -> bool {
1256 match other {
1257 IpAddr::V4(v4) => self == v4,
1258 IpAddr::V6(_) => false,
1259 }
1260 }
1261}
1262
1263#[stable(feature = "rust1", since = "1.0.0")]
1264#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
1265const impl PartialOrd for Ipv4Addr {
1266 #[inline]
1267 fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
1268 Some(self.cmp(other))
1269 }
1270}
1271
1272#[stable(feature = "ip_cmp", since = "1.16.0")]
1273impl PartialOrd<Ipv4Addr> for IpAddr {
1274 #[inline]
1275 fn partial_cmp(&self, other: &Ipv4Addr) -> Option<Ordering> {
1276 match self {
1277 IpAddr::V4(v4) => v4.partial_cmp(other),
1278 IpAddr::V6(_) => Some(Ordering::Greater),
1279 }
1280 }
1281}
1282
1283#[stable(feature = "ip_cmp", since = "1.16.0")]
1284impl PartialOrd<IpAddr> for Ipv4Addr {
1285 #[inline]
1286 fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
1287 match other {
1288 IpAddr::V4(v4) => self.partial_cmp(v4),
1289 IpAddr::V6(_) => Some(Ordering::Less),
1290 }
1291 }
1292}
1293
1294#[stable(feature = "rust1", since = "1.0.0")]
1295#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
1296const impl Ord for Ipv4Addr {
1297 #[inline]
1298 fn cmp(&self, other: &Ipv4Addr) -> Ordering {
1299 self.octets.cmp(&other.octets)
1300 }
1301}
1302
1303#[stable(feature = "ip_u32", since = "1.1.0")]
1304#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1305const impl From<Ipv4Addr> for u32 {
1306 #[inline]
1308 fn from(ip: Ipv4Addr) -> u32 {
1309 ip.to_bits()
1310 }
1311}
1312
1313#[stable(feature = "ip_u32", since = "1.1.0")]
1314#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1315const impl From<u32> for Ipv4Addr {
1316 #[inline]
1318 fn from(ip: u32) -> Ipv4Addr {
1319 Ipv4Addr::from_bits(ip)
1320 }
1321}
1322
1323#[stable(feature = "from_slice_v4", since = "1.9.0")]
1324#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1325const impl From<[u8; 4]> for Ipv4Addr {
1326 #[inline]
1337 fn from(octets: [u8; 4]) -> Ipv4Addr {
1338 Ipv4Addr { octets }
1339 }
1340}
1341
1342#[stable(feature = "ip_from_slice", since = "1.17.0")]
1343#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
1344const impl From<[u8; 4]> for IpAddr {
1345 #[inline]
1356 fn from(octets: [u8; 4]) -> IpAddr {
1357 IpAddr::V4(Ipv4Addr::from(octets))
1358 }
1359}
1360
1361impl Ipv6Addr {
1362 #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
1374 #[stable(feature = "rust1", since = "1.0.0")]
1375 #[must_use]
1376 #[inline]
1377 pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, h: u16) -> Ipv6Addr {
1378 let addr16 = [
1379 a.to_be(),
1380 b.to_be(),
1381 c.to_be(),
1382 d.to_be(),
1383 e.to_be(),
1384 f.to_be(),
1385 g.to_be(),
1386 h.to_be(),
1387 ];
1388 Ipv6Addr {
1389 octets: unsafe { transmute::<_, [u8; 16]>(addr16) },
1392 }
1393 }
1394
1395 #[stable(feature = "ip_bits", since = "1.80.0")]
1405 pub const BITS: u32 = 128;
1406
1407 #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
1444 #[stable(feature = "ip_bits", since = "1.80.0")]
1445 #[must_use]
1446 #[inline]
1447 pub const fn to_bits(self) -> u128 {
1448 u128::from_be_bytes(self.octets)
1449 }
1450
1451 #[rustc_const_stable(feature = "ip_bits", since = "1.80.0")]
1469 #[stable(feature = "ip_bits", since = "1.80.0")]
1470 #[must_use]
1471 #[inline]
1472 pub const fn from_bits(bits: u128) -> Ipv6Addr {
1473 Ipv6Addr { octets: bits.to_be_bytes() }
1474 }
1475
1476 #[doc(alias = "IN6ADDR_LOOPBACK_INIT")]
1490 #[doc(alias = "in6addr_loopback")]
1491 #[stable(feature = "ip_constructors", since = "1.30.0")]
1492 pub const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
1493
1494 #[doc(alias = "IN6ADDR_ANY_INIT")]
1507 #[doc(alias = "in6addr_any")]
1508 #[stable(feature = "ip_constructors", since = "1.30.0")]
1509 pub const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
1510
1511 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1522 #[stable(feature = "rust1", since = "1.0.0")]
1523 #[must_use]
1524 #[inline]
1525 pub const fn segments(&self) -> [u16; 8] {
1526 let [a, b, c, d, e, f, g, h] = unsafe { transmute::<_, [u16; 8]>(self.octets) };
1529 [
1531 u16::from_be(a),
1532 u16::from_be(b),
1533 u16::from_be(c),
1534 u16::from_be(d),
1535 u16::from_be(e),
1536 u16::from_be(f),
1537 u16::from_be(g),
1538 u16::from_be(h),
1539 ]
1540 }
1541
1542 #[stable(feature = "ip_from", since = "1.91.0")]
1562 #[rustc_const_stable(feature = "ip_from", since = "1.91.0")]
1563 #[must_use]
1564 #[inline]
1565 pub const fn from_segments(segments: [u16; 8]) -> Ipv6Addr {
1566 let [a, b, c, d, e, f, g, h] = segments;
1567 Ipv6Addr::new(a, b, c, d, e, f, g, h)
1568 }
1569
1570 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1585 #[stable(since = "1.7.0", feature = "ip_17")]
1586 #[must_use]
1587 #[inline]
1588 pub const fn is_unspecified(&self) -> bool {
1589 u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::UNSPECIFIED.octets())
1590 }
1591
1592 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1609 #[stable(since = "1.7.0", feature = "ip_17")]
1610 #[must_use]
1611 #[inline]
1612 pub const fn is_loopback(&self) -> bool {
1613 u128::from_be_bytes(self.octets()) == u128::from_be_bytes(Ipv6Addr::LOCALHOST.octets())
1614 }
1615
1616 #[unstable(feature = "ip", issue = "27709")]
1682 #[must_use]
1683 #[inline]
1684 pub const fn is_global(&self) -> bool {
1685 !(self.is_unspecified()
1686 || self.is_loopback()
1687 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0, 0, 0, 0, 0, 0xffff, _, _] => true,
_ => false,
}matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
1689 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x64, 0xff9b, 1, _, _, _, _, _] => true,
_ => false,
}matches!(self.segments(), [0x64, 0xff9b, 1, _, _, _, _, _])
1691 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x100, 0, 0, 0, _, _, _, _] => true,
_ => false,
}matches!(self.segments(), [0x100, 0, 0, 0, _, _, _, _])
1693 || (#[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2001, b, _, _, _, _, _, _] if b < 0x200 => true,
_ => false,
}matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b < 0x200)
1695 && !(
1696 u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0001
1698 || u128::from_be_bytes(self.octets()) == 0x2001_0001_0000_0000_0000_0000_0000_0002
1700 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2001, 3, _, _, _, _, _, _] => true,
_ => false,
}matches!(self.segments(), [0x2001, 3, _, _, _, _, _, _])
1702 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2001, 4, 0x112, _, _, _, _, _] => true,
_ => false,
}matches!(self.segments(), [0x2001, 4, 0x112, _, _, _, _, _])
1704 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x3F => true,
_ => false,
}matches!(self.segments(), [0x2001, b, _, _, _, _, _, _] if b >= 0x20 && b <= 0x3F)
1707 ))
1708 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2002, _, _, _, _, _, _, _] => true,
_ => false,
}matches!(self.segments(), [0x2002, _, _, _, _, _, _, _])
1711 || self.is_documentation()
1712 || #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x5f00, ..] => true,
_ => false,
}matches!(self.segments(), [0x5f00, ..])
1714 || self.is_unique_local()
1715 || self.is_unicast_link_local())
1716 }
1717
1718 #[must_use]
1733 #[inline]
1734 #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1735 #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1736 pub const fn is_unique_local(&self) -> bool {
1737 (self.segments()[0] & 0xfe00) == 0xfc00
1738 }
1739
1740 #[unstable(feature = "ip", issue = "27709")]
1762 #[must_use]
1763 #[inline]
1764 pub const fn is_unicast(&self) -> bool {
1765 !self.is_multicast()
1766 }
1767
1768 #[must_use]
1811 #[inline]
1812 #[stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1813 #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "1.84.0")]
1814 pub const fn is_unicast_link_local(&self) -> bool {
1815 (self.segments()[0] & 0xffc0) == 0xfe80
1816 }
1817
1818 #[unstable(feature = "ip", issue = "27709")]
1838 #[must_use]
1839 #[inline]
1840 pub const fn is_documentation(&self) -> bool {
1841 #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0x2001, 0xdb8, ..] | [0x3fff, 0..=0x0fff, ..] => true,
_ => false,
}matches!(self.segments(), [0x2001, 0xdb8, ..] | [0x3fff, 0..=0x0fff, ..])
1842 }
1843
1844 #[unstable(feature = "ip", issue = "27709")]
1861 #[must_use]
1862 #[inline]
1863 pub const fn is_benchmarking(&self) -> bool {
1864 (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
1865 }
1866
1867 #[unstable(feature = "ip", issue = "27709")]
1898 #[must_use]
1899 #[inline]
1900 pub const fn is_unicast_global(&self) -> bool {
1901 self.is_unicast()
1902 && !self.is_loopback()
1903 && !self.is_unicast_link_local()
1904 && !self.is_unique_local()
1905 && !self.is_unspecified()
1906 && !self.is_documentation()
1907 && !self.is_benchmarking()
1908 }
1909
1910 #[unstable(feature = "ip", issue = "27709")]
1926 #[must_use]
1927 #[inline]
1928 pub const fn multicast_scope(&self) -> Option<Ipv6MulticastScope> {
1929 if self.is_multicast() {
1930 match self.segments()[0] & 0x000f {
1931 0x0 => Some(Ipv6MulticastScope::Reserved0),
1932 0x1 => Some(Ipv6MulticastScope::InterfaceLocal),
1933 0x2 => Some(Ipv6MulticastScope::LinkLocal),
1934 0x3 => Some(Ipv6MulticastScope::RealmLocal),
1935 0x4 => Some(Ipv6MulticastScope::AdminLocal),
1936 0x5 => Some(Ipv6MulticastScope::SiteLocal),
1937 0x6 => Some(Ipv6MulticastScope::Unassigned6),
1938 0x7 => Some(Ipv6MulticastScope::Unassigned7),
1939 0x8 => Some(Ipv6MulticastScope::OrganizationLocal),
1940 0x9 => Some(Ipv6MulticastScope::Unassigned9),
1941 0xA => Some(Ipv6MulticastScope::UnassignedA),
1942 0xB => Some(Ipv6MulticastScope::UnassignedB),
1943 0xC => Some(Ipv6MulticastScope::UnassignedC),
1944 0xD => Some(Ipv6MulticastScope::UnassignedD),
1945 0xE => Some(Ipv6MulticastScope::Global),
1946 0xF => Some(Ipv6MulticastScope::ReservedF),
1947 _ => crate::panicking::panic("internal error: entered unreachable code")unreachable!(),
1948 }
1949 } else {
1950 None
1951 }
1952 }
1953
1954 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
1969 #[stable(since = "1.7.0", feature = "ip_17")]
1970 #[must_use]
1971 #[inline]
1972 pub const fn is_multicast(&self) -> bool {
1973 (self.segments()[0] & 0xff00) == 0xff00
1974 }
1975
1976 #[unstable(feature = "ip", issue = "27709")]
1994 #[must_use]
1995 #[inline]
1996 pub const fn is_ipv4_mapped(&self) -> bool {
1997 #[allow(non_exhaustive_omitted_patterns)] match self.segments() {
[0, 0, 0, 0, 0, 0xffff, _, _] => true,
_ => false,
}matches!(self.segments(), [0, 0, 0, 0, 0, 0xffff, _, _])
1998 }
1999
2000 #[inline]
2021 #[must_use = "this returns the result of the operation, \
2022 without modifying the original"]
2023 #[stable(feature = "ipv6_to_ipv4_mapped", since = "1.63.0")]
2024 #[rustc_const_stable(feature = "const_ipv6_to_ipv4_mapped", since = "1.75.0")]
2025 pub const fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
2026 match self.octets() {
2027 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, a, b, c, d] => {
2028 Some(Ipv4Addr::new(a, b, c, d))
2029 }
2030 _ => None,
2031 }
2032 }
2033
2034 #[rustc_const_stable(feature = "const_ip_50", since = "1.50.0")]
2063 #[stable(feature = "rust1", since = "1.0.0")]
2064 #[must_use = "this returns the result of the operation, \
2065 without modifying the original"]
2066 #[inline]
2067 pub const fn to_ipv4(&self) -> Option<Ipv4Addr> {
2068 if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
2069 let [a, b] = ab.to_be_bytes();
2070 let [c, d] = cd.to_be_bytes();
2071 Some(Ipv4Addr::new(a, b, c, d))
2072 } else {
2073 None
2074 }
2075 }
2076
2077 #[inline]
2089 #[must_use = "this returns the result of the operation, \
2090 without modifying the original"]
2091 #[stable(feature = "ip_to_canonical", since = "1.75.0")]
2092 #[rustc_const_stable(feature = "ip_to_canonical", since = "1.75.0")]
2093 pub const fn to_canonical(&self) -> IpAddr {
2094 if let Some(mapped) = self.to_ipv4_mapped() {
2095 return IpAddr::V4(mapped);
2096 }
2097 IpAddr::V6(*self)
2098 }
2099
2100 #[rustc_const_stable(feature = "const_ip_32", since = "1.32.0")]
2109 #[stable(feature = "ipv6_to_octets", since = "1.12.0")]
2110 #[must_use]
2111 #[inline]
2112 pub const fn octets(&self) -> [u8; 16] {
2113 self.octets
2114 }
2115
2116 #[stable(feature = "ip_from", since = "1.91.0")]
2136 #[rustc_const_stable(feature = "ip_from", since = "1.91.0")]
2137 #[must_use]
2138 #[inline]
2139 pub const fn from_octets(octets: [u8; 16]) -> Ipv6Addr {
2140 Ipv6Addr { octets }
2141 }
2142
2143 #[unstable(feature = "ip_as_octets", issue = "137259")]
2157 #[inline]
2158 pub const fn as_octets(&self) -> &[u8; 16] {
2159 &self.octets
2160 }
2161}
2162
2163#[stable(feature = "rust1", since = "1.0.0")]
2166impl fmt::Display for Ipv6Addr {
2167 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2168 if f.precision().is_none() && f.width().is_none() {
2171 let segments = self.segments();
2172
2173 if let Some(ipv4) = self.to_ipv4_mapped() {
2174 f.write_fmt(format_args!("::ffff:{0}", ipv4))write!(f, "::ffff:{}", ipv4)
2175 } else {
2176 #[derive(#[automatically_derived]
impl crate::marker::Copy for Span { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl crate::clone::TrivialClone for Span { }
#[automatically_derived]
impl crate::clone::Clone for Span {
#[inline]
fn clone(&self) -> Span {
let _: crate::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl crate::default::Default for Span {
#[inline]
fn default() -> Span {
Span {
start: crate::default::Default::default(),
len: crate::default::Default::default(),
}
}
}Default)]
2177 struct Span {
2178 start: usize,
2179 len: usize,
2180 }
2181
2182 let zeroes = {
2184 let mut longest = Span::default();
2185 let mut current = Span::default();
2186
2187 for (i, &segment) in segments.iter().enumerate() {
2188 if segment == 0 {
2189 if current.len == 0 {
2190 current.start = i;
2191 }
2192
2193 current.len += 1;
2194
2195 if current.len > longest.len {
2196 longest = current;
2197 }
2198 } else {
2199 current = Span::default();
2200 }
2201 }
2202
2203 longest
2204 };
2205
2206 #[inline]
2208 fn fmt_subslice(f: &mut fmt::Formatter<'_>, chunk: &[u16]) -> fmt::Result {
2209 if let Some((first, tail)) = chunk.split_first() {
2210 f.write_fmt(format_args!("{0:x}", first))write!(f, "{:x}", first)?;
2211 for segment in tail {
2212 f.write_char(':')?;
2213 f.write_fmt(format_args!("{0:x}", segment))write!(f, "{:x}", segment)?;
2214 }
2215 }
2216 Ok(())
2217 }
2218
2219 if zeroes.len > 1 {
2220 fmt_subslice(f, &segments[..zeroes.start])?;
2221 f.write_str("::")?;
2222 fmt_subslice(f, &segments[zeroes.start + zeroes.len..])
2223 } else {
2224 fmt_subslice(f, &segments)
2225 }
2226 }
2227 } else {
2228 const LONGEST_IPV6_ADDR: &str = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
2229
2230 let mut buf = DisplayBuffer::buffer::<{ LONGEST_IPV6_ADDR.len() }>();
2231 let mut buf = DisplayBuffer::new(&mut buf);
2232 buf.write_fmt(format_args!("{0}", self))write!(buf, "{}", self).unwrap();
2234
2235 f.pad(buf.as_str())
2236 }
2237 }
2238}
2239
2240#[stable(feature = "rust1", since = "1.0.0")]
2241impl fmt::Debug for Ipv6Addr {
2242 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2243 fmt::Display::fmt(self, fmt)
2244 }
2245}
2246
2247#[stable(feature = "ip_cmp", since = "1.16.0")]
2248impl PartialEq<IpAddr> for Ipv6Addr {
2249 #[inline]
2250 fn eq(&self, other: &IpAddr) -> bool {
2251 match other {
2252 IpAddr::V4(_) => false,
2253 IpAddr::V6(v6) => self == v6,
2254 }
2255 }
2256}
2257
2258#[stable(feature = "ip_cmp", since = "1.16.0")]
2259impl PartialEq<Ipv6Addr> for IpAddr {
2260 #[inline]
2261 fn eq(&self, other: &Ipv6Addr) -> bool {
2262 match self {
2263 IpAddr::V4(_) => false,
2264 IpAddr::V6(v6) => v6 == other,
2265 }
2266 }
2267}
2268
2269#[stable(feature = "rust1", since = "1.0.0")]
2270#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
2271const impl PartialOrd for Ipv6Addr {
2272 #[inline]
2273 fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
2274 Some(self.cmp(other))
2275 }
2276}
2277
2278#[stable(feature = "ip_cmp", since = "1.16.0")]
2279impl PartialOrd<Ipv6Addr> for IpAddr {
2280 #[inline]
2281 fn partial_cmp(&self, other: &Ipv6Addr) -> Option<Ordering> {
2282 match self {
2283 IpAddr::V4(_) => Some(Ordering::Less),
2284 IpAddr::V6(v6) => v6.partial_cmp(other),
2285 }
2286 }
2287}
2288
2289#[stable(feature = "ip_cmp", since = "1.16.0")]
2290impl PartialOrd<IpAddr> for Ipv6Addr {
2291 #[inline]
2292 fn partial_cmp(&self, other: &IpAddr) -> Option<Ordering> {
2293 match other {
2294 IpAddr::V4(_) => Some(Ordering::Greater),
2295 IpAddr::V6(v6) => self.partial_cmp(v6),
2296 }
2297 }
2298}
2299
2300#[stable(feature = "rust1", since = "1.0.0")]
2301#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
2302const impl Ord for Ipv6Addr {
2303 #[inline]
2304 fn cmp(&self, other: &Ipv6Addr) -> Ordering {
2305 self.segments().cmp(&other.segments())
2306 }
2307}
2308
2309#[stable(feature = "i128", since = "1.26.0")]
2310#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2311const impl From<Ipv6Addr> for u128 {
2312 #[inline]
2314 fn from(ip: Ipv6Addr) -> u128 {
2315 ip.to_bits()
2316 }
2317}
2318#[stable(feature = "i128", since = "1.26.0")]
2319#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2320const impl From<u128> for Ipv6Addr {
2321 #[inline]
2323 fn from(ip: u128) -> Ipv6Addr {
2324 Ipv6Addr::from_bits(ip)
2325 }
2326}
2327
2328#[stable(feature = "ipv6_from_octets", since = "1.9.0")]
2329#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2330const impl From<[u8; 16]> for Ipv6Addr {
2331 #[inline]
2351 fn from(octets: [u8; 16]) -> Ipv6Addr {
2352 Ipv6Addr { octets }
2353 }
2354}
2355
2356#[stable(feature = "ipv6_from_segments", since = "1.16.0")]
2357#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2358const impl From<[u16; 8]> for Ipv6Addr {
2359 #[inline]
2379 fn from(segments: [u16; 8]) -> Ipv6Addr {
2380 let [a, b, c, d, e, f, g, h] = segments;
2381 Ipv6Addr::new(a, b, c, d, e, f, g, h)
2382 }
2383}
2384
2385#[stable(feature = "ip_from_slice", since = "1.17.0")]
2386#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2387const impl From<[u8; 16]> for IpAddr {
2388 #[inline]
2408 fn from(octets: [u8; 16]) -> IpAddr {
2409 IpAddr::V6(Ipv6Addr::from(octets))
2410 }
2411}
2412
2413#[stable(feature = "ip_from_slice", since = "1.17.0")]
2414#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2415const impl From<[u16; 8]> for IpAddr {
2416 #[inline]
2436 fn from(segments: [u16; 8]) -> IpAddr {
2437 IpAddr::V6(Ipv6Addr::from(segments))
2438 }
2439}
2440
2441#[stable(feature = "ip_bitops", since = "1.75.0")]
2442#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2443const impl Not for Ipv4Addr {
2444 type Output = Ipv4Addr;
2445
2446 #[inline]
2447 fn not(mut self) -> Ipv4Addr {
2448 let mut idx = 0;
2449 while idx < 4 {
2450 self.octets[idx] = !self.octets[idx];
2451 idx += 1;
2452 }
2453 self
2454 }
2455}
2456
2457#[stable(feature = "ip_bitops", since = "1.75.0")]
2458#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2459const impl Not for &'_ Ipv4Addr {
2460 type Output = Ipv4Addr;
2461
2462 #[inline]
2463 fn not(self) -> Ipv4Addr {
2464 !*self
2465 }
2466}
2467
2468#[stable(feature = "ip_bitops", since = "1.75.0")]
2469#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2470const impl Not for Ipv6Addr {
2471 type Output = Ipv6Addr;
2472
2473 #[inline]
2474 fn not(mut self) -> Ipv6Addr {
2475 let mut idx = 0;
2476 while idx < 16 {
2477 self.octets[idx] = !self.octets[idx];
2478 idx += 1;
2479 }
2480 self
2481 }
2482}
2483
2484#[stable(feature = "ip_bitops", since = "1.75.0")]
2485#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2486const impl Not for &'_ Ipv6Addr {
2487 type Output = Ipv6Addr;
2488
2489 #[inline]
2490 fn not(self) -> Ipv6Addr {
2491 !*self
2492 }
2493}
2494
2495macro_rules! bitop_impls {
2496 ($(
2497 $(#[$attr:meta])*
2498 impl ($BitOp:ident, $BitOpAssign:ident) for $ty:ty = ($bitop:ident, $bitop_assign:ident);
2499 )*) => {
2500 $(
2501 $(#[$attr])*
2502 const impl $BitOpAssign for $ty {
2503 fn $bitop_assign(&mut self, rhs: $ty) {
2504 let mut idx = 0;
2505 while idx < self.octets.len() {
2506 self.octets[idx].$bitop_assign(rhs.octets[idx]);
2507 idx += 1;
2508 }
2509 }
2510 }
2511
2512 $(#[$attr])*
2513 const impl $BitOpAssign<&'_ $ty> for $ty {
2514 fn $bitop_assign(&mut self, rhs: &'_ $ty) {
2515 self.$bitop_assign(*rhs);
2516 }
2517 }
2518
2519 $(#[$attr])*
2520 const impl $BitOp for $ty {
2521 type Output = $ty;
2522
2523 #[inline]
2524 fn $bitop(mut self, rhs: $ty) -> $ty {
2525 self.$bitop_assign(rhs);
2526 self
2527 }
2528 }
2529
2530 $(#[$attr])*
2531 const impl $BitOp<&'_ $ty> for $ty {
2532 type Output = $ty;
2533
2534 #[inline]
2535 fn $bitop(mut self, rhs: &'_ $ty) -> $ty {
2536 self.$bitop_assign(*rhs);
2537 self
2538 }
2539 }
2540
2541 $(#[$attr])*
2542 const impl $BitOp<$ty> for &'_ $ty {
2543 type Output = $ty;
2544
2545 #[inline]
2546 fn $bitop(self, rhs: $ty) -> $ty {
2547 let mut lhs = *self;
2548 lhs.$bitop_assign(rhs);
2549 lhs
2550 }
2551 }
2552
2553 $(#[$attr])*
2554 const impl $BitOp<&'_ $ty> for &'_ $ty {
2555 type Output = $ty;
2556
2557 #[inline]
2558 fn $bitop(self, rhs: &'_ $ty) -> $ty {
2559 let mut lhs = *self;
2560 lhs.$bitop_assign(*rhs);
2561 lhs
2562 }
2563 }
2564 )*
2565 };
2566}
2567
2568#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAndAssign for Ipv4Addr {
fn bitand_assign(&mut self, rhs: Ipv4Addr) {
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].bitand_assign(rhs.octets[idx]);
idx += 1;
}
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAndAssign<&'_ Ipv4Addr> for Ipv4Addr {
fn bitand_assign(&mut self, rhs: &'_ Ipv4Addr) {
self.bitand_assign(*rhs);
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd for Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitand(mut self, rhs: Ipv4Addr) -> Ipv4Addr {
self.bitand_assign(rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<&'_ Ipv4Addr> for Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitand(mut self, rhs: &'_ Ipv4Addr) -> Ipv4Addr {
self.bitand_assign(*rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<Ipv4Addr> for &'_ Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitand(self, rhs: Ipv4Addr) -> Ipv4Addr {
let mut lhs = *self;
lhs.bitand_assign(rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<&'_ Ipv4Addr> for &'_ Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitand(self, rhs: &'_ Ipv4Addr) -> Ipv4Addr {
let mut lhs = *self;
lhs.bitand_assign(*rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOrAssign for Ipv4Addr {
fn bitor_assign(&mut self, rhs: Ipv4Addr) {
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].bitor_assign(rhs.octets[idx]);
idx += 1;
}
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOrAssign<&'_ Ipv4Addr> for Ipv4Addr {
fn bitor_assign(&mut self, rhs: &'_ Ipv4Addr) { self.bitor_assign(*rhs); }
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr for Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitor(mut self, rhs: Ipv4Addr) -> Ipv4Addr {
self.bitor_assign(rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<&'_ Ipv4Addr> for Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitor(mut self, rhs: &'_ Ipv4Addr) -> Ipv4Addr {
self.bitor_assign(*rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<Ipv4Addr> for &'_ Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitor(self, rhs: Ipv4Addr) -> Ipv4Addr {
let mut lhs = *self;
lhs.bitor_assign(rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<&'_ Ipv4Addr> for &'_ Ipv4Addr {
type Output = Ipv4Addr;
#[inline]
fn bitor(self, rhs: &'_ Ipv4Addr) -> Ipv4Addr {
let mut lhs = *self;
lhs.bitor_assign(*rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAndAssign for Ipv6Addr {
fn bitand_assign(&mut self, rhs: Ipv6Addr) {
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].bitand_assign(rhs.octets[idx]);
idx += 1;
}
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAndAssign<&'_ Ipv6Addr> for Ipv6Addr {
fn bitand_assign(&mut self, rhs: &'_ Ipv6Addr) {
self.bitand_assign(*rhs);
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd for Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitand(mut self, rhs: Ipv6Addr) -> Ipv6Addr {
self.bitand_assign(rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<&'_ Ipv6Addr> for Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitand(mut self, rhs: &'_ Ipv6Addr) -> Ipv6Addr {
self.bitand_assign(*rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<Ipv6Addr> for &'_ Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitand(self, rhs: Ipv6Addr) -> Ipv6Addr {
let mut lhs = *self;
lhs.bitand_assign(rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitAnd<&'_ Ipv6Addr> for &'_ Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitand(self, rhs: &'_ Ipv6Addr) -> Ipv6Addr {
let mut lhs = *self;
lhs.bitand_assign(*rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOrAssign for Ipv6Addr {
fn bitor_assign(&mut self, rhs: Ipv6Addr) {
let mut idx = 0;
while idx < self.octets.len() {
self.octets[idx].bitor_assign(rhs.octets[idx]);
idx += 1;
}
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOrAssign<&'_ Ipv6Addr> for Ipv6Addr {
fn bitor_assign(&mut self, rhs: &'_ Ipv6Addr) { self.bitor_assign(*rhs); }
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr for Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitor(mut self, rhs: Ipv6Addr) -> Ipv6Addr {
self.bitor_assign(rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<&'_ Ipv6Addr> for Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitor(mut self, rhs: &'_ Ipv6Addr) -> Ipv6Addr {
self.bitor_assign(*rhs);
self
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<Ipv6Addr> for &'_ Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitor(self, rhs: Ipv6Addr) -> Ipv6Addr {
let mut lhs = *self;
lhs.bitor_assign(rhs);
lhs
}
}
#[stable(feature = "ip_bitops", since = "1.75.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "143802")]
const impl BitOr<&'_ Ipv6Addr> for &'_ Ipv6Addr {
type Output = Ipv6Addr;
#[inline]
fn bitor(self, rhs: &'_ Ipv6Addr) -> Ipv6Addr {
let mut lhs = *self;
lhs.bitor_assign(*rhs);
lhs
}
}bitop_impls! {
2569 #[stable(feature = "ip_bitops", since = "1.75.0")]
2570 #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2571 impl (BitAnd, BitAndAssign) for Ipv4Addr = (bitand, bitand_assign);
2572 #[stable(feature = "ip_bitops", since = "1.75.0")]
2573 #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2574 impl (BitOr, BitOrAssign) for Ipv4Addr = (bitor, bitor_assign);
2575
2576 #[stable(feature = "ip_bitops", since = "1.75.0")]
2577 #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2578 impl (BitAnd, BitAndAssign) for Ipv6Addr = (bitand, bitand_assign);
2579 #[stable(feature = "ip_bitops", since = "1.75.0")]
2580 #[rustc_const_unstable(feature = "const_ops", issue = "143802")]
2581 impl (BitOr, BitOrAssign) for Ipv6Addr = (bitor, bitor_assign);
2582}