// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// TODO: Edit this doc comment (it's copy+pasted from the Netstack3 core)

//! Internet Protocol (IP) types.
//!
//! This module provides support for various types and traits relating to IPv4
//! and IPv6, including a number of mechanisms for abstracting over details
//! which are shared between IPv4 and IPv6.
//!
//! # `Ip` and `IpAddress`
//!
//! The most important traits are [`Ip`] and [`IpAddress`].
//!
//! `Ip` represents a version of the IP protocol - either IPv4 or IPv6 - and is
//! implemented by [`Ipv4`] and [`Ipv6`]. These types exist only at the type
//! level - they cannot be constructed at runtime. They provide a place to put
//! constants and functionality which are not associated with a particular type,
//! and they allow code to be written which is generic over the version of the
//! IP protocol. For example:
//!
//! ```rust
//! # use net_types::ip::{Ip, IpAddress, Subnet};
//! struct Entry<A: IpAddress> {
//!     subnet: Subnet<A>,
//!     dest: Destination<A>,
//! }
//!
//! enum Destination<A: IpAddress> {
//!     Local { device_id: usize },
//!     Remote { dst: A },
//! }
//!
//! struct ForwardingTable<I: Ip> {
//!     entries: Vec<Entry<I::Addr>>,
//! }
//! ```
//!
//! See also [`IpVersionMarker`].
//!
//! The `IpAddress` trait is implemented by the concrete [`Ipv4Addr`] and
//! [`Ipv6Addr`] types.
//!
//! # Runtime types
//!
//! Sometimes, it is not known at compile time which version of a given type -
//! IPv4 or IPv6 - is present. For these cases, enums are provided with variants
//! for both IPv4 and IPv6. These are [`IpAddr`], [`SubnetEither`], and
//! [`AddrSubnetEither`].
//!
//! # Composite types
//!
//! This modules also provides composite types such as [`Subnet`] and
//! [`AddrSubnet`].

use core::fmt::{self, Debug, Display, Formatter};
use core::hash::Hash;
use core::mem;
use core::ops::{Deref, DerefMut};

#[cfg(feature = "std")]
use std::net;

pub use net_types_macros::GenericOverIp;
use zerocopy::{AsBytes, FromBytes, FromZeros, NoCell, Unaligned};

use crate::{
    sealed, LinkLocalAddr, LinkLocalAddress, MappedAddress, MulticastAddr, MulticastAddress,
    NonMappedAddr, Scope, ScopeableAddress, SpecifiedAddr, SpecifiedAddress, UnicastAddr,
    UnicastAddress, Witness,
};

// NOTE on passing by reference vs by value: Clippy advises us to pass IPv4
// addresses by value, and IPv6 addresses by reference. For concrete types, we
// do the right thing. For the IpAddress trait, we use references in order to
// optimize (albeit very slightly) for IPv6 performance.

/// An IP protocol version.
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpVersion {
    V4,
    V6,
}

/// Evaluates `expression` for any given `ip_version`.
///
/// `type_param` will be defined to be [`crate::ip::Ipv4`] for
/// [`crate::ip::IpVersion::V4`], and [`crate::ip::Ipv6`] for
/// [`crate::ip::IpVersion::V6`].
///
/// Example usage:
///
/// ```
/// let ip_version: IpVersion = foo();
/// for_any_ip_version!(ip_version, I, some_ip_generic_fn::<I>());
/// ```
#[macro_export]
macro_rules! for_any_ip_version {
    ($ip_version:expr, $type_param:ident, $expression:expr) => {
        match $ip_version {
            $crate::ip::IpVersion::V4 => {
                type $type_param = $crate::ip::Ipv4;
                $expression
            }
            $crate::ip::IpVersion::V6 => {
                type $type_param = $crate::ip::Ipv6;
                $expression
            }
        }
    };
}

/// A zero-sized type that carries IP version information.
///
/// `IpVersionMarker` is typically used by types that are generic over IP
/// version, but without any other associated data. In this sense,
/// `IpVersionMarker` behaves similarly to [`PhantomData`].
///
/// [`PhantomData`]: core::marker::PhantomData
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, GenericOverIp)]
#[generic_over_ip(I, Ip)]
pub struct IpVersionMarker<I: Ip> {
    _marker: core::marker::PhantomData<I>,
}

impl<I: Ip> IpVersionMarker<I> {
    /// Creates a new `IpVersionMarker`.
    // TODO(https://github.com/rust-lang/rust/issues/67792): Remove once
    // `const_trait_impl` is stabilized.
    pub const fn new() -> Self {
        Self { _marker: core::marker::PhantomData }
    }
}

impl<I: Ip> Default for IpVersionMarker<I> {
    fn default() -> Self {
        Self { _marker: core::marker::PhantomData }
    }
}

impl<I: Ip> Debug for IpVersionMarker<I> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "IpVersionMarker<{}>", I::NAME)
    }
}

/// An IP address.
///
/// By default, the contained address types are [`Ipv4Addr`] and [`Ipv6Addr`].
/// However, any types can be provided. This is intended to support types like
/// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>`. `From` is
/// implemented to support conversions in both directions between
/// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>` and
/// `SpecifiedAddr<IpAddr>`, and similarly for other witness types.
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash, PartialOrd, Ord)]
pub enum IpAddr<V4 = Ipv4Addr, V6 = Ipv6Addr> {
    V4(V4),
    V6(V6),
}

impl<V4: Display, V6: Display> Display for IpAddr<V4, V6> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        match self {
            Self::V4(v4) => v4.fmt(f),
            Self::V6(v6) => v6.fmt(f),
        }
    }
}

impl<V4, V6> IpAddr<V4, V6> {
    /// Transposes an `IpAddr` of a witness type to a witness type of an
    /// `IpAddr`.
    ///
    /// For example, `transpose` can be used to convert an
    /// `IpAddr<SpecifiedAddr<Ipv4Addr>, SpecifiedAddr<Ipv6Addr>>` into a
    /// `SpecifiedAddr<IpAddr<Ipv4Addr, Ipv6Addr>>`.
    pub fn transpose<W: IpAddrWitness<V4 = V4, V6 = V6>>(self) -> W {
        match self {
            IpAddr::V4(addr) => W::from_v4(addr),
            IpAddr::V6(addr) => W::from_v6(addr),
        }
    }
}

impl<A: IpAddress> From<A> for IpAddr {
    #[inline]
    fn from(addr: A) -> IpAddr {
        addr.to_ip_addr()
    }
}

impl<A: IpAddress, const N: usize> From<[A; N]> for IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
    #[inline]
    fn from(addrs: [A; N]) -> Self {
        A::array_into_ip_addr(addrs)
    }
}

#[cfg(feature = "std")]
impl From<net::IpAddr> for IpAddr {
    #[inline]
    fn from(addr: net::IpAddr) -> IpAddr {
        match addr {
            net::IpAddr::V4(addr) => IpAddr::V4(addr.into()),
            net::IpAddr::V6(addr) => IpAddr::V6(addr.into()),
        }
    }
}

#[cfg(feature = "std")]
impl From<IpAddr> for net::IpAddr {
    fn from(addr: IpAddr) -> net::IpAddr {
        match addr {
            IpAddr::V4(addr) => net::IpAddr::V4(addr.into()),
            IpAddr::V6(addr) => net::IpAddr::V6(addr.into()),
        }
    }
}

impl IpVersion {
    /// The number for this IP protocol version.
    ///
    /// 4 for `V4` and 6 for `V6`.
    #[inline]
    pub fn version_number(self) -> u8 {
        match self {
            IpVersion::V4 => 4,
            IpVersion::V6 => 6,
        }
    }

    /// Is this IPv4?
    #[inline]
    pub fn is_v4(self) -> bool {
        self == IpVersion::V4
    }

    /// Is this IPv6?
    #[inline]
    pub fn is_v6(self) -> bool {
        self == IpVersion::V6
    }
}

/// The maximum transmit unit, i.e., the maximum size of an entire IP packet
/// one link can transmit.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Mtu(u32);

impl Mtu {
    /// Creates MTU from the maximum size of an entire IP packet in bytes.
    pub const fn new(mtu: u32) -> Self {
        Self(mtu)
    }

    /// Gets the numeric value of the MTU.
    pub const fn get(&self) -> u32 {
        let Self(mtu) = self;
        *mtu
    }
}

impl From<Mtu> for u32 {
    fn from(Mtu(mtu): Mtu) -> Self {
        mtu
    }
}

/// A trait for IP protocol versions.
///
/// `Ip` encapsulates the details of a version of the IP protocol. It includes a
/// runtime representation of the protocol version ([`VERSION`]), the type of
/// addresses for this version ([`Addr`]), and a number of constants which exist
/// in both protocol versions. This trait is sealed, and there are guaranteed to
/// be no other implementors besides these. Code - including unsafe code - may
/// rely on this assumption for its correctness and soundness.
///
/// Note that the implementors of this trait cannot be instantiated; they only
/// exist at the type level.
///
/// [`VERSION`]: Ip::VERSION
/// [`Addr`]: Ip::Addr
pub trait Ip:
    Sized
    + Clone
    + Copy
    + Debug
    + Default
    + Eq
    + Hash
    + Ord
    + PartialEq
    + PartialOrd
    + Send
    + Sync
    + sealed::Sealed
    + 'static
{
    /// The IP version.
    ///
    /// `V4` for IPv4 and `V6` for IPv6.
    const VERSION: IpVersion;

    /// The zero-sized-type IP version marker.
    const VERSION_MARKER: IpVersionMarker<Self>;

    /// The unspecified address.
    ///
    /// This is 0.0.0.0 for IPv4 and :: for IPv6.
    const UNSPECIFIED_ADDRESS: Self::Addr;

    /// The default loopback address.
    ///
    /// When sending packets to a loopback interface, this address is used as
    /// the source address. It is an address in the [`LOOPBACK_SUBNET`].
    ///
    /// [`LOOPBACK_SUBNET`]: Ip::LOOPBACK_SUBNET
    const LOOPBACK_ADDRESS: SpecifiedAddr<Self::Addr>;

    /// The subnet of loopback addresses.
    ///
    /// Addresses in this subnet must not appear outside a host, and may only be
    /// used for loopback interfaces.
    const LOOPBACK_SUBNET: Subnet<Self::Addr>;

    /// The subnet of multicast addresses.
    const MULTICAST_SUBNET: Subnet<Self::Addr>;

    /// The subnet of link-local unicast addresses.
    ///
    /// Note that some multicast addresses are also link-local. In IPv4, these
    /// are contained in the [link-local multicast subnet]. In IPv6, the
    /// link-local multicast addresses are not organized into a single subnet;
    /// instead, whether a multicast IPv6 address is link-local is a function of
    /// its scope.
    ///
    /// [link-local multicast subnet]: Ipv4::LINK_LOCAL_MULTICAST_SUBNET
    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Self::Addr>;

    /// "IPv4" or "IPv6".
    const NAME: &'static str;

    /// The minimum link MTU for this version.
    ///
    /// Every internet link supporting this IP version must have a maximum
    /// transmission unit (MTU) of at least this many bytes. This MTU applies to
    /// the size of an IP packet, and does not include any extra bytes used by
    /// encapsulating packets (Ethernet frames, GRE packets, etc).
    const MINIMUM_LINK_MTU: Mtu;

    /// The address type for this IP version.
    ///
    /// [`Ipv4Addr`] for IPv4 and [`Ipv6Addr`] for IPv6.
    type Addr: IpAddress<Version = Self>
        + GenericOverIp<Self, Type = Self::Addr>
        + GenericOverIp<Ipv4, Type = Ipv4Addr>
        + GenericOverIp<Ipv6, Type = Ipv6Addr>;

    /// Apply one of the given functions to the input and return the result.
    ///
    /// This makes it possible to implement specialized behavior for IPv4 and
    /// IPv6 versions that is more versatile than matching on [`Ip::VERSION`].
    /// With a `match` expression, all branches must produce a value of the
    /// same type. `map_ip` relaxes that restriction by instead requiring that
    /// inputs and outputs are [`GenericOverIp`].
    ///
    /// Using `map_ip`, you can write generic code with specialized
    /// implementations for different IP versions where some or all of the input
    /// and output arguments have a type parameter `I: Ip`. As an example,
    /// consider the following:
    ///
    /// ```
    /// // Swaps the order of the addresses only if `I=Ipv4`.
    /// fn swap_only_if_ipv4<I: Ip>(addrs: (I::Addr, I::Addr)) -> (I::Addr, I::Addr) {
    ///    I::map_ip::<(I::Addr, I::Addr), (I::Addr, I::Addr)>(
    ///        addrs,
    ///        |(a, b): (Ipv4Addr, Ipv4Addr)| (b, a),
    ///        |ab: (Ipv6Addr, Ipv6Addr)| ab
    ///    )
    /// }
    /// ```
    ///
    /// Note that the input and output arguments both depend on the type
    /// parameter `I`, but the closures take an [`Ipv4Addr`] or [`Ipv6Addr`].
    ///
    /// Types that don't implement `GenericOverIp` can be wrapped in
    /// [`IpInvariant`], which implements `GenericOverIp` assuming the type
    /// inside doesn't have any IP-related components.
    fn map_ip<
        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
    >(
        input: In,
        v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
        v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
    ) -> Out;
}

/// Invokes `I::map_ip`, passing the same function body as both arguments.
///
/// The first argument is always the `I` on which to invoke `I::map_ip`.
/// Optionally, this can include an alias (`I as IpAlias`) that should be bound
/// to `Ipv4` and `Ipv6` for each instantiation of the function body. (If the
/// `Ip` argument passed is a simple identifier, then it is automatically
/// aliased in this way.)
/// The next argument is the input to thread through `map_ip` to the function,
/// and the final argument is the function to be duplicated to serve as the
/// closures passed to `map_ip`.
///
/// This macro helps avoid code duplication when working with types that are
/// _not_ GenericOverIp, but have identical shapes such that the actual text of
/// the code you are writing is identical. This should be very rare, and is
/// generally limited to cases where we are interfacing with code that we don't
/// have the ability to make generic-over-IP -- when possible, it's better to
/// push `I: Ip` generics further through the types you are working with instead
/// so that you can avoid using `map_ip` entirely.
///
/// Example:
///
/// ```
/// // Imagine that `IpExt` is implemented for concrete `Ipv4` and `Ipv6` but
/// // not for blanket `I: Ip`.
/// struct Foo<I: IpExt>;
///
/// struct FooFactory;
/// impl FooFactory {
///     fn get<I: IpExt>(&self) -> Foo<I> {
///         unimplemented!()
///     }
/// }
///
/// struct FooSink<I: IpExt>;
/// impl<I: IpExt> FooSink<I> {
///     fn use_foo(&self, foo: Foo<I>) {
///         unimplemented!()
///     }
/// }
///
/// fn do_something<I: Ip>(factory: FooFactory) -> Foo<I> {
///     map_ip_twice!(
///         I,
///         (),
///         |()| {
///            // This works because even though the `I` from the function decl
///            // doesn't have an `IpExt` bound, it's aliased to either `Ipv4`
///            // or `Ipv6` here.
///            factory.get::<I>()
///         },
///     )
/// }
///
/// fn do_something_else<I: IpExt>(factory: FooFactory, foo_sink: FooSink<I>) {
///     map_ip_twice!(
///         // Introduce different alias to avoid shadowing `I`.
///         I as IpAlias,
///         (),
///         |()| {
///             let foo_with_orig_ip = factory.get::<I>();
///             // The fact that `I` was not shadowed allows us to make use of
///             // `foo_sink` by capture rather than needing to thread it
///             // through the generic-over-IP input.
///             foo_sink.use_foo(foo_with_orig_ip)
///         },
///     )
/// }
/// ```
#[macro_export]
macro_rules! map_ip_twice {
    // This case triggers if we're passed an `Ip` implementor that is a simple
    // identifier in-scope (e.g. `I`), which allows us to automatically alias it
    // to `Ipv4` and `Ipv6` in each `$fn` instantiation.
    ($ip:ident, $input:expr, $fn:expr $(,)?) => {
        $crate::map_ip_twice!($ip as $ip, $input, $fn)
    };
    // This case triggers if we're passed an `Ip` implementor that is _not_ an
    // identifier, and thus we can't use it as the left-hand-side of a type
    // alias binding (e.g. `<A as IpAddress>::Version`).
    ($ip:ty, $input:expr, $fn:expr $(,)?) => {
        <$ip as $crate::ip::Ip>::map_ip($input, { $fn }, { $fn })
    };
    ($ip:ty as $iptypealias:ident, $input:expr, $fn:expr $(,)?) => {
        <$ip as $crate::ip::Ip>::map_ip(
            $input,
            {
                #[allow(dead_code)]
                type $iptypealias = $crate::ip::Ipv4;
                $fn
            },
            {
                #[allow(dead_code)]
                type $iptypealias = $crate::ip::Ipv6;
                $fn
            },
        )
    };
}

/// IPv4.
///
/// `Ipv4` implements [`Ip`] for IPv4.
///
/// Note that this type has no value constructor. It is used purely at the type
/// level. Attempting to construct it by calling `Default::default` will panic.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Ipv4 {}

impl Default for Ipv4 {
    fn default() -> Ipv4 {
        panic!("Ipv4 default")
    }
}

impl sealed::Sealed for Ipv4 {}

impl Ip for Ipv4 {
    const VERSION: IpVersion = IpVersion::V4;
    const VERSION_MARKER: IpVersionMarker<Self> = IpVersionMarker::new();

    // TODO(https://fxbug.dev/42163997): Document the standard in which this
    // constant is defined.
    const UNSPECIFIED_ADDRESS: Ipv4Addr = Ipv4Addr::new([0, 0, 0, 0]);
    /// The default IPv4 address used for loopback, defined in [RFC 5735 Section
    /// 3].
    ///
    /// Note that while this address is the most commonly used address for
    /// loopback traffic, any address in the [`LOOPBACK_SUBNET`] may be used.
    ///
    /// [RFC 5735 Section 3]: https://datatracker.ietf.org/doc/html/rfc5735#section-3
    /// [`LOOPBACK_SUBNET`]: Ipv4::LOOPBACK_SUBNET
    const LOOPBACK_ADDRESS: SpecifiedAddr<Ipv4Addr> =
        unsafe { SpecifiedAddr::new_unchecked(Ipv4Addr::new([127, 0, 0, 1])) };
    /// The IPv4 loopback subnet, defined in [RFC 1122 Section 3.2.1.3].
    ///
    /// [RFC 1122 Section 3.2.1.3]: https://www.rfc-editor.org/rfc/rfc1122.html#section-3.2.1.3
    const LOOPBACK_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([127, 0, 0, 0]), prefix: 8 };
    /// The IPv4 Multicast subnet, defined in [RFC 1112 Section 4].
    ///
    /// [RFC 1112 Section 4]: https://www.rfc-editor.org/rfc/rfc1112.html#section-4
    const MULTICAST_SUBNET: Subnet<Ipv4Addr> = Self::CLASS_D_SUBNET;
    /// The subnet of link-local unicast IPv4 addresses, outlined in [RFC 3927
    /// Section 2.1].
    ///
    /// [RFC 3927 Section 2.1]: https://tools.ietf.org/html/rfc3927#section-2.1
    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([169, 254, 0, 0]), prefix: 16 };
    const NAME: &'static str = "IPv4";
    /// The IPv4 minimum link MTU.
    ///
    /// Per [RFC 791 Section 3.2], "[\e\]very internet module must be able to
    /// forward a datagram of 68 octets without further fragmentation."
    ///
    /// [RFC 791 Section 3.2]: https://tools.ietf.org/html/rfc791#section-3.2
    const MINIMUM_LINK_MTU: Mtu = Mtu(68);
    type Addr = Ipv4Addr;

    fn map_ip<
        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
    >(
        input: In,
        v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
        _v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
    ) -> Out {
        v4(input)
    }
}

impl Ipv4 {
    /// The limited broadcast address.
    ///
    /// The limited broadcast address is considered to be a broadcast address on
    /// all networks regardless of subnet address. This is distinct from the
    /// subnet-specific broadcast address (e.g., 192.168.255.255 on the subnet
    /// 192.168.0.0/16). It is defined in the [IANA IPv4 Special-Purpose Address
    /// Registry].
    ///
    /// [IANA IPv4 Special-Purpose Address Registry]: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
    pub const LIMITED_BROADCAST_ADDRESS: SpecifiedAddr<Ipv4Addr> =
        unsafe { SpecifiedAddr::new_unchecked(Ipv4Addr::new([255, 255, 255, 255])) };

    /// The Class A subnet.
    ///
    /// The Class A subnet is defined in [RFC 1812 section 2.2.5.1].
    ///
    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
    pub const CLASS_A_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([0, 0, 0, 0]), prefix: 1 };

    /// The Class B subnet.
    ///
    /// The Class B subnet is defined in [RFC 1812 section 2.2.5.1].
    ///
    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
    pub const CLASS_B_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([128, 0, 0, 0]), prefix: 2 };

    /// The Class C subnet.
    ///
    /// The Class C subnet is defined in [RFC 1812 section 2.2.5.1].
    ///
    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
    pub const CLASS_C_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([192, 0, 0, 0]), prefix: 3 };

    /// The Class D subnet.
    ///
    /// This subnet is also known as the multicast subnet.
    ///
    /// The Class D subnet is defined in [RFC 1812 section 2.2.5.1].
    ///
    /// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
    pub const CLASS_D_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([224, 0, 0, 0]), prefix: 4 };

    /// The Class E subnet.
    ///
    /// The Class E subnet is meant for experimental purposes, and should not be
    /// used on the general internet. [RFC 1812 Section 5.3.7] suggests that
    /// routers SHOULD discard packets with a source address in the Class E
    /// subnet. The Class E subnet is defined in [RFC 1112 Section 4].
    ///
    /// [RFC 1812 Section 5.3.7]: https://tools.ietf.org/html/rfc1812#section-5.3.7
    /// [RFC 1112 Section 4]: https://datatracker.ietf.org/doc/html/rfc1112#section-4
    pub const CLASS_E_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([240, 0, 0, 0]), prefix: 4 };

    /// The subnet of link-local multicast addresses, outlined in [RFC 5771
    /// Section 4].
    ///
    /// [RFC 5771 Section 4]: https://tools.ietf.org/html/rfc5771#section-4
    pub const LINK_LOCAL_MULTICAST_SUBNET: Subnet<Ipv4Addr> =
        Subnet { network: Ipv4Addr::new([224, 0, 0, 0]), prefix: 24 };

    /// The multicast address subscribed to by all systems on the local network,
    /// defined in the [IPv4 Multicast Address Space Registry].
    ///
    /// [IPv4 Multicast Address Space Registry]: https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
    pub const ALL_SYSTEMS_MULTICAST_ADDRESS: MulticastAddr<Ipv4Addr> =
        unsafe { MulticastAddr::new_unchecked(Ipv4Addr::new([224, 0, 0, 1])) };

    /// The multicast address subscribed to by all routers on the local network,
    /// defined in the [IPv4 Multicast Address Space Registry].
    ///
    /// [IPv4 Multicast Address Space Registry]: https://www.iana.org/assignments/multicast-addresses/multicast-addresses.xhtml
    pub const ALL_ROUTERS_MULTICAST_ADDRESS: MulticastAddr<Ipv4Addr> =
        unsafe { MulticastAddr::new_unchecked(Ipv4Addr::new([224, 0, 0, 2])) };
}

/// IPv6.
///
/// `Ipv6` implements [`Ip`] for IPv6.
///
/// Note that this type has no value constructor. It is used purely at the type
/// level. Attempting to construct it by calling `Default::default` will panic.
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Ipv6 {}

impl Default for Ipv6 {
    fn default() -> Ipv6 {
        panic!("Ipv6 default")
    }
}

impl sealed::Sealed for Ipv6 {}

impl Ip for Ipv6 {
    const VERSION: IpVersion = IpVersion::V6;
    const VERSION_MARKER: IpVersionMarker<Self> = IpVersionMarker::new();
    /// The unspecified IPv6 address, defined in [RFC 4291 Section 2.5.2].
    ///
    /// Per RFC 4291:
    ///
    /// > The address 0:0:0:0:0:0:0:0 is called the unspecified address.  It
    /// > must never be assigned to any node.  It indicates the absence of an
    /// > address.  One example of its use is in the Source Address field of any
    /// > IPv6 packets sent by an initializing host before it has learned its
    /// > own address.
    /// >
    /// > The unspecified address must not be used as the destination address of
    /// > IPv6 packets or in IPv6 Routing headers.  An IPv6 packet with a source
    /// > address of unspecified must never be forwarded by an IPv6 router.
    ///
    /// [RFC 4291 Section 2.5.2]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.2
    const UNSPECIFIED_ADDRESS: Ipv6Addr = Ipv6Addr::new([0; 8]);
    /// The loopback IPv6 address, defined in [RFC 4291 Section 2.5.3].
    ///
    /// Per RFC 4291:
    ///
    /// > The unicast address 0:0:0:0:0:0:0:1 is called the loopback address.
    /// > It may be used by a node to send an IPv6 packet to itself.  It must
    /// > not be assigned to any physical interface.  It is treated as having
    /// > Link-Local scope, and may be thought of as the Link-Local unicast
    /// > address of a virtual interface (typically called the "loopback
    /// > interface") to an imaginary link that goes nowhere.
    /// >
    /// > The loopback address must not be used as the source address in IPv6
    /// > packets that are sent outside of a single node.  An IPv6 packet with
    /// > a destination address of loopback must never be sent outside of a
    /// > single node and must never be forwarded by an IPv6 router.  A packet
    /// > received on an interface with a destination address of loopback must
    /// > be dropped.
    ///
    /// [RFC 4291 Section 2.5.3]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.5.3
    const LOOPBACK_ADDRESS: SpecifiedAddr<Ipv6Addr> =
        unsafe { SpecifiedAddr::new_unchecked(Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1])) };
    /// The subnet of loopback IPv6 addresses, defined in [RFC 4291 Section 2.4].
    ///
    /// Note that the IPv6 loopback subnet is a /128, meaning that it contains
    /// only one address - the [`LOOPBACK_ADDRESS`].
    ///
    /// [RFC 4291 Section 2.4]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.4
    /// [`LOOPBACK_ADDRESS`]: Ipv6::LOOPBACK_ADDRESS
    const LOOPBACK_SUBNET: Subnet<Ipv6Addr> =
        Subnet { network: Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1]), prefix: 128 };
    /// The subnet of multicast IPv6 addresses, defined in [RFC 4291 Section
    /// 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://datatracker.ietf.org/doc/html/rfc4291#section-2.7
    const MULTICAST_SUBNET: Subnet<Ipv6Addr> =
        Subnet { network: Ipv6Addr::new([0xff00, 0, 0, 0, 0, 0, 0, 0]), prefix: 8 };
    /// The subnet of link-local unicast addresses, defined in [RFC 4291 Section
    /// 2.4].
    ///
    /// Note that multicast addresses can also be link-local. However, there is
    /// no single subnet of link-local multicast addresses. For more details on
    /// link-local multicast addresses, see [RFC 4291 Section 2.7].
    ///
    /// [RFC 4291 Section 2.4]: https://tools.ietf.org/html/rfc4291#section-2.4
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    const LINK_LOCAL_UNICAST_SUBNET: Subnet<Ipv6Addr> =
        Subnet { network: Ipv6Addr::new([0xfe80, 0, 0, 0, 0, 0, 0, 0]), prefix: 10 };
    const NAME: &'static str = "IPv6";
    /// The IPv6 minimum link MTU, defined in [RFC 8200 Section 5].
    ///
    /// Per RFC 8200:
    ///
    /// > IPv6 requires that every link in the Internet have an MTU of 1280
    /// > octets or greater. This is known as the IPv6 minimum link MTU. On any
    /// > link that cannot convey a 1280-octet packet in one piece, link-
    /// > specific fragmentation and reassembly must be provided at a layer
    /// > below IPv6.
    ///
    /// [RFC 8200 Section 5]: https://tools.ietf.org/html/rfc8200#section-5
    const MINIMUM_LINK_MTU: Mtu = Mtu(1280);
    type Addr = Ipv6Addr;

    fn map_ip<
        In: GenericOverIp<Self, Type = In> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
        Out: GenericOverIp<Self, Type = Out> + GenericOverIp<Ipv4> + GenericOverIp<Ipv6>,
    >(
        input: In,
        _v4: impl FnOnce(<In as GenericOverIp<Ipv4>>::Type) -> <Out as GenericOverIp<Ipv4>>::Type,
        v6: impl FnOnce(<In as GenericOverIp<Ipv6>>::Type) -> <Out as GenericOverIp<Ipv6>>::Type,
    ) -> Out {
        v6(input)
    }
}

impl Ipv6 {
    /// The loopback address represented as a [`UnicastAddr`].
    ///
    /// This is equivalent to [`LOOPBACK_ADDRESS`], except that it is a
    /// [`UnicastAddr`] witness type.
    ///
    /// [`LOOPBACK_ADDRESS`]: Ipv6::LOOPBACK_ADDRESS
    pub const LOOPBACK_IPV6_ADDRESS: UnicastAddr<Ipv6Addr> =
        unsafe { UnicastAddr::new_unchecked(Ipv6::LOOPBACK_ADDRESS.0) };

    /// The IPv6 All Nodes multicast address in link-local scope, defined in
    /// [RFC 4291 Section 2.7.1].
    ///
    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
    pub const ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS: MulticastAddr<Ipv6Addr> =
        unsafe { MulticastAddr::new_unchecked(Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0, 0, 1])) };

    /// The IPv6 All Routers multicast address in link-local scope, defined in
    /// [RFC 4291 Section 2.7.1].
    ///
    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
    pub const ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS: MulticastAddr<Ipv6Addr> =
        unsafe { MulticastAddr::new_unchecked(Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0, 0, 2])) };

    /// The (deprecated) subnet of site-local unicast addresses, defined in [RFC
    /// 3513 Section 2.5.6].
    ///
    /// The site-local unicast subnet was deprecated in [RFC 3879]:
    ///
    /// > The special behavior of this prefix MUST no longer be supported in new
    /// > implementations. The prefix MUST NOT be reassigned for other use
    /// > except by a future IETF standards action... However, router
    /// > implementations SHOULD be configured to prevent routing of this prefix
    /// > by default.
    ///
    /// [RFC 3513 Section 2.5.6]: https://tools.ietf.org/html/rfc3513#section-2.5.6
    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
    pub const SITE_LOCAL_UNICAST_SUBNET: Subnet<Ipv6Addr> =
        Subnet { network: Ipv6Addr::new([0xfec0, 0, 0, 0, 0, 0, 0, 0]), prefix: 10 };

    /// The length, in bits, of the interface identifier portion of unicast IPv6
    /// addresses *except* for addresses which start with the binary value 000.
    ///
    /// According to [RFC 4291 Section 2.5.1], "\[f\]or all unicast addresses,
    /// except those that start with the binary value 000, Interface IDs are
    /// required to be 64 bits."
    ///
    /// Note that, per [RFC 4862 Section 5.5.3]:
    ///
    /// > a future revision of the address architecture \[RFC4291\] and a future
    /// > link-type-specific document, which will still be consistent with each
    /// > other, could potentially allow for an interface identifier of length
    /// > other than the value defined in the current documents.  Thus, an
    /// > implementation should not assume a particular constant.  Rather, it
    /// > should expect any lengths of interface identifiers.
    ///
    /// In other words, this constant may be used to generate addresses or
    /// subnet prefix lengths, but should *not* be used to validate addresses or
    /// subnet prefix lengths generated by other software or other machines, as
    /// it might be valid for other software or other machines to use an
    /// interface identifier length different from this one.
    ///
    /// [RFC 4291 Section 2.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.1
    /// [RFC 4862 Section 5.5.3]: https://tools.ietf.org/html/rfc4862#section-5.5.3
    pub const UNICAST_INTERFACE_IDENTIFIER_BITS: u8 = 64;

    /// The length, in bits, of an IPv6 flow label, defined in [RFC 6437 Section 2].
    ///
    /// [RFC 6437 Section 2]: https://tools.ietf.org/html/rfc6437#section-2
    pub const FLOW_LABEL_BITS: u8 = 20;
}

/// An IPv4 or IPv6 address.
///
/// `IpAddress` is implemented by [`Ipv4Addr`] and [`Ipv6Addr`]. It is sealed,
/// and there are guaranteed to be no other implementors besides these. Code -
/// including unsafe code - may rely on this assumption for its correctness and
/// soundness.
pub trait IpAddress:
    Sized
    + Eq
    + PartialEq
    + PartialOrd
    + Ord
    + Hash
    + Copy
    + Display
    + Debug
    + Default
    + Sync
    + Send
    + LinkLocalAddress
    + ScopeableAddress
    + GenericOverIp<Self::Version, Type = Self>
    + GenericOverIp<Ipv4, Type = Ipv4Addr>
    + GenericOverIp<Ipv6, Type = Ipv6Addr>
    + sealed::Sealed
    + 'static
{
    /// The number of bytes in an address of this type.
    ///
    /// 4 for IPv4 and 16 for IPv6.
    const BYTES: u8;

    /// The IP version type of this address.
    ///
    /// [`Ipv4`] for [`Ipv4Addr`] and [`Ipv6`] for [`Ipv6Addr`].
    type Version: Ip<Addr = Self>;

    /// Gets the underlying bytes of the address.
    fn bytes(&self) -> &[u8];

    /// Masks off the top bits of the address.
    ///
    /// Returns a copy of `self` where all but the top `bits` bits are set to
    /// 0.
    ///
    /// # Panics
    ///
    /// `mask` panics if `bits` is out of range - if it is greater than 32 for
    /// IPv4 or greater than 128 for IPv6.
    fn mask(&self, bits: u8) -> Self;

    /// Converts a statically-typed IP address into a dynamically-typed one.
    fn to_ip_addr(&self) -> IpAddr;

    /// Is this a loopback address?
    ///
    /// `is_loopback` returns `true` if this address is a member of the
    /// [`LOOPBACK_SUBNET`].
    ///
    /// [`LOOPBACK_SUBNET`]: Ip::LOOPBACK_SUBNET
    #[inline]
    fn is_loopback(&self) -> bool {
        Self::Version::LOOPBACK_SUBNET.contains(self)
    }

    /// Calculates the common prefix length between this address and `other`.
    fn common_prefix_len(&self, other: &Self) -> u8;

    /// Is this a unicast address contained in the given subnet?
    ///
    /// `is_unicast_in_subnet` returns `true` if the given subnet contains this
    /// address and the address is none of:
    /// - a multicast address
    /// - the IPv4 limited broadcast address
    /// - the IPv4 subnet-specific broadcast address for the given subnet
    /// - an IPv4 address whose host bits (those bits following the network
    ///   prefix) are all 0
    /// - the unspecified address
    /// - an IPv4 Class E address
    ///
    /// Note two exceptions to these rules: If `subnet` is an IPv4 /32, then the
    /// single unicast address in the subnet is also technically the subnet
    /// broadcast address. If `subnet` is an IPv4 /31, then both addresses in
    /// that subnet are broadcast addresses. In either case, the "no
    /// subnet-specific broadcast" and "no address with a host part of all
    /// zeroes" rules don't apply. Note further that this exception *doesn't*
    /// apply to the unspecified address, which is never considered a unicast
    /// address regardless of what subnet it's in.
    ///
    /// # RFC Deep Dive
    ///
    /// ## IPv4 addresses ending in zeroes
    ///
    /// In this section, we justify the rule that IPv4 addresses whose host bits
    /// are all 0 are not considered unicast addresses.
    ///
    /// In earlier standards, an IPv4 address whose bits were all 0 after the
    /// network prefix (e.g., 192.168.0.0 in the subnet 192.168.0.0/16) were a
    /// form of "network-prefix-directed" broadcast addresses. Similarly,
    /// 0.0.0.0 was considered a form of "limited broadcast address" (equivalent
    /// to 255.255.255.255). These have since been deprecated (in the case of
    /// 0.0.0.0, it is now considered the "unspecified" address).
    ///
    /// As evidence that this deprecation is official, consider [RFC 1812
    /// Section 5.3.5]. In reference to these types of addresses, it states that
    /// "packets addressed to any of these addresses SHOULD be silently
    /// discarded \[by routers\]". This not only deprecates them as broadcast
    /// addresses, but also as unicast addresses (after all, unicast addresses
    /// are not particularly useful if packets destined to them are discarded by
    /// routers).
    ///
    /// ## IPv4 /31 and /32 exceptions
    ///
    /// In this section, we justify the exceptions that all addresses in IPv4
    /// /31 and /32 subnets are considered unicast.
    ///
    /// For /31 subnets, the case is easy. [RFC 3021 Section 2.1] states that
    /// both addresses in a /31 subnet "MUST be interpreted as host addresses."
    ///
    /// For /32, the case is a bit more vague. RFC 3021 makes no mention of /32
    /// subnets. However, the same reasoning applies - if an exception is not
    /// made, then there do not exist any host addresses in a /32 subnet. [RFC
    /// 4632 Section 3.1] also vaguely implies this interpretation by referring
    /// to addresses in /32 subnets as "host routes."
    ///
    /// [RFC 1812 Section 5.3.5]: https://tools.ietf.org/html/rfc1812#page-92
    /// [RFC 4632 Section 3.1]: https://tools.ietf.org/html/rfc4632#section-3.1
    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool;

    // Functions used to implement internal types. These functions aren't
    // particularly useful to users, but allow us to implement certain
    // specialization-like behavior without actually relying on the unstable
    // `specialization` feature.

    #[doc(hidden)]
    fn subnet_into_either(subnet: Subnet<Self>) -> SubnetEither;

    #[doc(hidden)]
    fn array_into_ip_addr<const N: usize>(addrs: [Self; N])
        -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]>;
}

impl<A: IpAddress> SpecifiedAddress for A {
    /// Is this an address other than the unspecified address?
    ///
    /// `is_specified` returns true if `self` is not equal to
    /// [`A::Version::UNSPECIFIED_ADDRESS`].
    ///
    /// [`A::Version::UNSPECIFIED_ADDRESS`]: Ip::UNSPECIFIED_ADDRESS
    #[inline]
    fn is_specified(&self) -> bool {
        self != &A::Version::UNSPECIFIED_ADDRESS
    }
}

/// Maps a method over an `IpAddr`, calling it after matching on the type of IP
/// address.
macro_rules! map_ip_addr {
    ($val:expr, $method:ident) => {
        match $val {
            IpAddr::V4(a) => a.$method(),
            IpAddr::V6(a) => a.$method(),
        }
    };
}

impl SpecifiedAddress for IpAddr {
    /// Is this an address other than the unspecified address?
    ///
    /// `is_specified` returns true if `self` is not equal to
    /// [`Ip::UNSPECIFIED_ADDRESS`] for the IP version of this address.
    #[inline]
    fn is_specified(&self) -> bool {
        map_ip_addr!(self, is_specified)
    }
}

impl<A: IpAddress> MulticastAddress for A {
    /// Is this address in the multicast subnet?
    ///
    /// `is_multicast` returns true if `self` is in
    /// [`A::Version::MULTICAST_SUBNET`].
    ///
    /// [`A::Version::MULTICAST_SUBNET`]: Ip::MULTICAST_SUBNET
    #[inline]
    fn is_multicast(&self) -> bool {
        <A as IpAddress>::Version::MULTICAST_SUBNET.contains(self)
    }
}

impl MulticastAddress for IpAddr {
    /// Is this an address in the multicast subnet?
    ///
    /// `is_multicast` returns true if `self` is in [`Ip::MULTICAST_SUBNET`] for
    /// the IP version of this address.
    #[inline]
    fn is_multicast(&self) -> bool {
        map_ip_addr!(self, is_multicast)
    }
}

impl LinkLocalAddress for Ipv4Addr {
    /// Is this address in the link-local subnet?
    ///
    /// `is_link_local` returns true if `self` is in
    /// [`Ipv4::LINK_LOCAL_UNICAST_SUBNET`] or
    /// [`Ipv4::LINK_LOCAL_MULTICAST_SUBNET`].
    #[inline]
    fn is_link_local(&self) -> bool {
        Ipv4::LINK_LOCAL_UNICAST_SUBNET.contains(self)
            || Ipv4::LINK_LOCAL_MULTICAST_SUBNET.contains(self)
    }
}

impl LinkLocalAddress for Ipv6Addr {
    /// Is this address in the link-local subnet?
    ///
    /// `is_link_local` returns true if `self` is in
    /// [`Ipv6::LINK_LOCAL_UNICAST_SUBNET`], is a multicast address whose scope
    /// is link-local, or is the address [`Ipv6::LOOPBACK_ADDRESS`] (per [RFC
    /// 4291 Section 2.5.3], the loopback address is considered to have
    /// link-local scope).
    ///
    /// [RFC 4291 Section 2.5.3]: https://tools.ietf.org/html/rfc4291#section-2.5.3
    #[inline]
    fn is_link_local(&self) -> bool {
        Ipv6::LINK_LOCAL_UNICAST_SUBNET.contains(self)
            || (self.is_multicast() && self.scope() == Ipv6Scope::LinkLocal)
            || self == Ipv6::LOOPBACK_ADDRESS.deref()
    }
}

impl LinkLocalAddress for IpAddr {
    /// Is this address link-local?
    #[inline]
    fn is_link_local(&self) -> bool {
        map_ip_addr!(self, is_link_local)
    }
}

impl<A: IpAddress> MappedAddress for A {
    /// Is this address non-mapped?
    ///
    /// For IPv4 addresses, this always returns true because they do not have a
    /// mapped address space.
    ///
    /// For Ipv6 addresses, this returns true if `self` is outside of the IPv4
    /// mapped Ipv6 address subnet, as defined in [RFC 4291 Section 2.5.5.2]
    /// (e.g. `::FFFF:0:0/96`).
    ///
    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
    #[inline]
    fn is_non_mapped(&self) -> bool {
        A::Version::map_ip(self, |_addr_v4| true, |addr_v6| addr_v6.to_ipv4_mapped().is_none())
    }
}

impl MappedAddress for IpAddr {
    /// Is this address non-mapped?
    #[inline]
    fn is_non_mapped(&self) -> bool {
        map_ip_addr!(self, is_non_mapped)
    }
}

impl<I: Ip> GenericOverIp<I> for Ipv4Addr {
    type Type = I::Addr;
}

impl<I: Ip> GenericOverIp<I> for Ipv6Addr {
    type Type = I::Addr;
}

impl ScopeableAddress for Ipv4Addr {
    type Scope = ();

    /// The scope of this address.
    ///
    /// Although IPv4 defines a link local subnet, IPv4 addresses are always
    /// considered to be in the global scope.
    fn scope(&self) {}
}

/// The list of IPv6 scopes.
///
/// These scopes are defined by [RFC 4291 Section 2.7].
///
/// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Ipv6Scope {
    /// The interface-local scope.
    InterfaceLocal,
    /// The link-local scope.
    LinkLocal,
    /// The admin-local scope.
    AdminLocal,
    /// The (deprecated) site-local scope.
    ///
    /// The site-local scope was deprecated in [RFC 3879]. While this scope
    /// is returned for both site-local unicast and site-local multicast
    /// addresses, RFC 3879 says the following about site-local unicast addresses
    /// in particular ("this prefix" refers to the [site-local unicast subnet]):
    ///
    /// > The special behavior of this prefix MUST no longer be supported in new
    /// > implementations. The prefix MUST NOT be reassigned for other use
    /// > except by a future IETF standards action... However, router
    /// > implementations SHOULD be configured to prevent routing of this prefix
    /// > by default.
    ///
    /// [RFC 3879]: https://tools.ietf.org/html/rfc3879
    /// [site-local unicast subnet]: Ipv6::SITE_LOCAL_UNICAST_SUBNET
    SiteLocal,
    /// The organization-local scope.
    OrganizationLocal,
    /// The global scope.
    Global,
    /// Scopes which are reserved for future use by [RFC 4291 Section 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    Reserved(Ipv6ReservedScope),
    /// Scopes which are available for local definition by administrators.
    Unassigned(Ipv6UnassignedScope),
}

/// The list of IPv6 scopes which are reserved for future use by [RFC 4291
/// Section 2.7].
///
/// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Ipv6ReservedScope {
    /// The scope with numerical value 0.
    Scope0 = 0,
    /// The scope with numerical value 3.
    Scope3 = 3,
    /// The scope with numerical value 0xF.
    ScopeF = 0xF,
}

/// The list of IPv6 scopes which are available for local definition by
/// administrators.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Ipv6UnassignedScope {
    /// The scope with numerical value 6.
    Scope6 = 6,
    /// The scope with numerical value 7.
    Scope7 = 7,
    /// The scope with numerical value 9.
    Scope9 = 9,
    /// The scope with numerical value 0xA.
    ScopeA = 0xA,
    /// The scope with numerical value 0xB.
    ScopeB = 0xB,
    /// The scope with numerical value 0xC.
    ScopeC = 0xC,
    /// The scope with numerical value 0xD.
    ScopeD = 0xD,
}

impl Scope for Ipv6Scope {
    #[inline]
    fn can_have_zone(&self) -> bool {
        // Per RFC 6874 Section 4:
        //
        // > [I]mplementations MUST NOT allow use of this format except for
        // > well-defined usages, such as sending to link-local addresses under
        // > prefix fe80::/10.  At the time of writing, this is the only
        // > well-defined usage known.
        //
        // While this directive applies particularly to the human-readable
        // string representation of IPv6 addresses and zone identifiers, it
        // seems reasonable to limit the in-memory representation in the same
        // way.
        //
        // Note that, if interpreted literally, this quote would bar the use of
        // zone identifiers on link-local multicast addresses (they are not
        // under the prefix fe80::/10). However, it seems clear that this is not
        // the interpretation that was intended. Link-local multicast addresses
        // have the same need for a zone identifier as link-local unicast
        // addresses, and indeed, real systems like Linux allow link-local
        // multicast addresses to be accompanied by zone identifiers.
        matches!(self, Ipv6Scope::LinkLocal)
    }
}

impl Ipv6Scope {
    /// The multicast scope ID of an interface-local address, defined in [RFC
    /// 4291 Section 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_INTERFACE_LOCAL: u8 = 1;

    /// The multicast scope ID of a link-local address, defined in [RFC 4291
    /// Section 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_LINK_LOCAL: u8 = 2;

    /// The multicast scope ID of an admin-local address, defined in [RFC 4291
    /// Section 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_ADMIN_LOCAL: u8 = 4;

    /// The multicast scope ID of a (deprecated) site-local address, defined in
    /// [RFC 4291 Section 2.7].
    ///
    /// Note that site-local addresses are deprecated.
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_SITE_LOCAL: u8 = 5;

    /// The multicast scope ID of an organization-local address, defined in [RFC
    /// 4291 Section 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_ORG_LOCAL: u8 = 8;

    /// The multicast scope ID of global address, defined in [RFC 4291 Section
    /// 2.7].
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub const MULTICAST_SCOPE_ID_GLOBAL: u8 = 0xE;

    /// The ID used to indicate this scope in a multicast IPv6 address.
    ///
    /// Per [RFC 4291 Section 2.7], the bits of a multicast IPv6 address are
    /// laid out as follows:
    ///
    /// ```text
    /// |   8    |  4 |  4 |                  112 bits                   |
    /// +------ -+----+----+---------------------------------------------+
    /// |11111111|flgs|scop|                  group ID                   |
    /// +--------+----+----+---------------------------------------------+
    /// ```
    ///
    /// The 4-bit scop field encodes the scope of the address.
    /// `multicast_scope_id` returns the numerical value used to encode this
    /// scope in the scop field of a multicast address.
    ///
    /// [RFC 4291 Section 2.7]: https://tools.ietf.org/html/rfc4291#section-2.7
    pub fn multicast_scope_id(&self) -> u8 {
        match self {
            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope0) => 0,
            Ipv6Scope::InterfaceLocal => Self::MULTICAST_SCOPE_ID_INTERFACE_LOCAL,
            Ipv6Scope::LinkLocal => Self::MULTICAST_SCOPE_ID_LINK_LOCAL,
            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope3) => 3,
            Ipv6Scope::AdminLocal => Self::MULTICAST_SCOPE_ID_ADMIN_LOCAL,
            Ipv6Scope::SiteLocal => Self::MULTICAST_SCOPE_ID_SITE_LOCAL,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope6) => 6,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope7) => 7,
            Ipv6Scope::OrganizationLocal => Self::MULTICAST_SCOPE_ID_ORG_LOCAL,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope9) => 9,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeA) => 0xA,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeB) => 0xB,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeC) => 0xC,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeD) => 0xD,
            Ipv6Scope::Global => Self::MULTICAST_SCOPE_ID_GLOBAL,
            Ipv6Scope::Reserved(Ipv6ReservedScope::ScopeF) => 0xF,
        }
    }
}

impl ScopeableAddress for Ipv6Addr {
    type Scope = Ipv6Scope;

    /// The scope of this address.
    #[inline]
    fn scope(&self) -> Ipv6Scope {
        if self.is_multicast() {
            use Ipv6ReservedScope::*;
            use Ipv6Scope::*;
            use Ipv6UnassignedScope::*;

            // The "scop" field of a multicast address is the last 4 bits of the
            // second byte of the address (see
            // https://tools.ietf.org/html/rfc4291#section-2.7).
            match self.0[1] & 0xF {
                0 => Reserved(Scope0),
                Ipv6Scope::MULTICAST_SCOPE_ID_INTERFACE_LOCAL => InterfaceLocal,
                Ipv6Scope::MULTICAST_SCOPE_ID_LINK_LOCAL => LinkLocal,
                3 => Reserved(Scope3),
                Ipv6Scope::MULTICAST_SCOPE_ID_ADMIN_LOCAL => AdminLocal,
                Ipv6Scope::MULTICAST_SCOPE_ID_SITE_LOCAL => SiteLocal,
                6 => Unassigned(Scope6),
                7 => Unassigned(Scope7),
                Ipv6Scope::MULTICAST_SCOPE_ID_ORG_LOCAL => OrganizationLocal,
                9 => Unassigned(Scope9),
                0xA => Unassigned(ScopeA),
                0xB => Unassigned(ScopeB),
                0xC => Unassigned(ScopeC),
                0xD => Unassigned(ScopeD),
                Ipv6Scope::MULTICAST_SCOPE_ID_GLOBAL => Global,
                0xF => Reserved(ScopeF),
                _ => unreachable!(),
            }
        } else if self.is_link_local() {
            Ipv6Scope::LinkLocal
        } else if self.is_site_local() {
            Ipv6Scope::SiteLocal
        } else {
            Ipv6Scope::Global
        }
    }
}

impl Scope for IpAddr<(), Ipv6Scope> {
    #[inline]
    fn can_have_zone(&self) -> bool {
        match self {
            IpAddr::V4(scope) => scope.can_have_zone(),
            IpAddr::V6(scope) => scope.can_have_zone(),
        }
    }
}

impl ScopeableAddress for IpAddr {
    type Scope = IpAddr<(), Ipv6Scope>;

    #[inline]
    fn scope(&self) -> IpAddr<(), Ipv6Scope> {
        match self {
            IpAddr::V4(_) => IpAddr::V4(()),
            IpAddr::V6(addr) => IpAddr::V6(addr.scope()),
        }
    }
}

// The definition of each trait for `IpAddr` is equal to the definition of that
// trait for whichever of `Ipv4Addr` and `Ipv6Addr` is actually present in the
// enum. Thus, we can convert between `$witness<IpvXAddr>`, `$witness<IpAddr>`,
// and `IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>` arbitrarily.

/// Provides various useful `From` impls for an IP address witness type.
///
/// `impl_from_witness!($witness)` implements:
/// - `From<IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>> for
///   $witness<IpAddr>`
/// - `From<$witness<IpAddr>> for IpAddr<$witness<Ipv4Addr>,
///   $witness<Ipv6Addr>>`
/// - `From<$witness<A>> for $witness<A>`
/// - `From<$witness<Ipv4Addr>> for IpAddr`
/// - `From<$witness<Ipv6Addr>> for IpAddr`
/// - `TryFrom<Ipv4Addr> for $witness<Ipv4Addr>`
/// - `TryFrom<Ipv6Addr> for $witness<Ipv6Addr>`
///
/// `impl_from_witness!($witness, $ipaddr, $new_unchecked)` implements:
/// - `From<$witness<$ipaddr>> for $witness<IpAddr>`
/// - `From<$witness<$ipaddr>> for $ipaddr`
/// - `TryFrom<$ipaddr> for $witness<$ipaddr>`
macro_rules! impl_from_witness {
    ($witness:ident, $witness_trait:ident) => {
        impl From<IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>> for $witness<IpAddr> {
            fn from(addr: IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>>) -> $witness<IpAddr> {
                unsafe {
                    Witness::new_unchecked(match addr {
                        IpAddr::V4(addr) => IpAddr::V4(addr.get()),
                        IpAddr::V6(addr) => IpAddr::V6(addr.get()),
                    })
                }
            }
        }
        impl From<$witness<IpAddr>> for IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
            fn from(addr: $witness<IpAddr>) -> IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
                unsafe {
                    match addr.get() {
                        IpAddr::V4(addr) => IpAddr::V4(Witness::new_unchecked(addr)),
                        IpAddr::V6(addr) => IpAddr::V6(Witness::new_unchecked(addr)),
                    }
                }
            }
        }
        impl<A: IpAddress> From<$witness<A>> for $witness<IpAddr> {
            fn from(addr: $witness<A>) -> $witness<IpAddr> {
                unsafe { Witness::new_unchecked(addr.to_ip_addr()) }
            }
        }
        impl<A: IpAddress> From<$witness<A>> for IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
            fn from(addr: $witness<A>) -> IpAddr<$witness<Ipv4Addr>, $witness<Ipv6Addr>> {
                let addr: $witness<IpAddr> = addr.into();
                addr.into()
            }
        }
        // NOTE: Orphan rules prevent implementing `From` for `A: IpAddress`.
        impl<A: Into<Ipv4Addr> + $witness_trait + Copy> From<$witness<A>> for Ipv4Addr {
            fn from(addr: $witness<A>) -> Ipv4Addr {
                let addr: A = addr.get();
                addr.into()
            }
        }
        impl<A: Into<Ipv6Addr> + $witness_trait + Copy> From<$witness<A>> for Ipv6Addr {
            fn from(addr: $witness<A>) -> Ipv6Addr {
                let addr: A = addr.get();
                addr.into()
            }
        }
        // NOTE: Orphan rules prevent implementing `TryFrom` for `A: IpAddress`.
        impl TryFrom<Ipv4Addr> for $witness<Ipv4Addr> {
            type Error = ();
            fn try_from(addr: Ipv4Addr) -> Result<$witness<Ipv4Addr>, ()> {
                Witness::new(addr).ok_or(())
            }
        }
        impl TryFrom<Ipv6Addr> for $witness<Ipv6Addr> {
            type Error = ();
            fn try_from(addr: Ipv6Addr) -> Result<$witness<Ipv6Addr>, ()> {
                Witness::new(addr).ok_or(())
            }
        }
    };
    ($witness:ident, $witness_trait:ident, $ipaddr:ident, $new_unchecked:expr) => {
        impl From<$witness<$ipaddr>> for $witness<IpAddr> {
            fn from(addr: $witness<$ipaddr>) -> $witness<IpAddr> {
                let addr: $ipaddr = addr.get();
                let addr: IpAddr = addr.into();
                #[allow(unused_unsafe)] // For when a closure is passed
                unsafe {
                    $new_unchecked(addr)
                }
            }
        }
        impl<A: Into<$ipaddr> + $witness_trait + Copy> From<$witness<A>> for $ipaddr {
            fn from(addr: $witness<A>) -> $ipaddr {
                let addr: A = addr.get();
                addr.into()
            }
        }
        impl TryFrom<$ipaddr> for $witness<$ipaddr> {
            type Error = ();
            fn try_from(addr: $ipaddr) -> Result<$witness<$ipaddr>, ()> {
                Witness::new(addr).ok_or(())
            }
        }
    };
}

impl_from_witness!(SpecifiedAddr, SpecifiedAddress);
impl_from_witness!(MulticastAddr, MulticastAddress);
impl_from_witness!(LinkLocalAddr, LinkLocalAddress);
impl_from_witness!(NonMappedAddr, MappedAddress);
// Only add `From` conversions for `Ipv6Addr`, because `Ipv4Addr` does not
// implement `UnicastAddress`.
impl_from_witness!(UnicastAddr, UnicastAddress, Ipv6Addr, UnicastAddr::new_unchecked);

/// The class of an IPv4 address.
///
/// The classful addressing scheme is obsoloted in favour of [CIDR] but is still
/// used on some systems. For more information, see [RFC 791 section 2.3] and
/// [RFC 1812 section 2.2.5.1].
///
/// [CIDR]: https://datatracker.ietf.org/doc/html/rfc1518
/// [RFC 791 section 2.3]: https://datatracker.ietf.org/doc/html/rfc791#section-2.3
/// [RFC 1812 section 2.2.5.1]: https://datatracker.ietf.org/doc/html/rfc1812#section-2.2.5.1
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Ipv4AddressClass {
    /// A Class A IPv4 address.
    A,
    /// A Class B IPv4 address.
    B,
    /// A Class C IPv4 address.
    C,
    /// A Class D IPv4 address.
    ///
    /// Class D addresses are also known as multicast.
    D,
    /// A Class E IPv4 address.
    ///
    /// Class E addresses are also known as experimental.
    E,
}

impl Ipv4AddressClass {
    /// Returns the default prefix length for an IPv4 address class if the
    /// prefix is well-defined.
    pub const fn default_prefix_len(self) -> Option<u8> {
        // Per RFC 943 https://datatracker.ietf.org/doc/html/rfc943
        //
        //   The first type of address, or class A, has a 7-bit network number
        //   and a 24-bit local address.  The highest-order bit is set to 0.
        //   This allows 128 class A networks.
        //
        //                        1                   2                   3
        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //   |0|   NETWORK   |                Local Address                  |
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //
        //                          Class A Address
        //
        //   The second type of address, class B, has a 14-bit network number
        //   and a 16-bit local address.  The two highest-order bits are set to
        //   1-0.  This allows 16,384 class B networks.
        //
        //                        1                   2                   3
        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //   |1 0|           NETWORK         |          Local Address        |
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //
        //                          Class B Address
        //
        //   The third type of address, class C, has a 21-bit network number
        //   and a 8-bit local address.  The three highest-order bits are set
        //   to 1-1-0.  This allows 2,097,152 class C networks.
        //
        //                        1                   2                   3
        //    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //   |1 1 0|                    NETWORK              | Local Address |
        //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        //
        //                          Class C Address
        match self {
            Ipv4AddressClass::A => Some(8),
            Ipv4AddressClass::B => Some(16),
            Ipv4AddressClass::C => Some(24),
            Ipv4AddressClass::D => None,
            Ipv4AddressClass::E => None,
        }
    }
}

/// An IPv4 address.
///
/// # Layout
///
/// `Ipv4Addr` has the same layout as `[u8; 4]`, which is the layout that most
/// protocols use to represent an IPv4 address in their packet formats. This can
/// be useful when parsing an IPv4 address from a packet. For example:
///
/// ```rust
/// # use net_types::ip::Ipv4Addr;
/// /// An ICMPv4 Redirect Message header.
/// ///
/// /// `Icmpv4RedirectHeader` has the same layout as the header of an ICMPv4
/// /// Redirect Message.
/// #[repr(C)]
/// struct Icmpv4RedirectHeader {
///     typ: u8,
///     code: u8,
///     checksum: [u8; 2],
///     gateway: Ipv4Addr,
/// }
/// ```
#[derive(
    Copy,
    Clone,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    FromZeros,
    FromBytes,
    AsBytes,
    NoCell,
    Unaligned,
)]
#[repr(transparent)]
pub struct Ipv4Addr([u8; 4]);

impl Ipv4Addr {
    /// Creates a new IPv4 address.
    #[inline]
    pub const fn new(bytes: [u8; 4]) -> Self {
        Ipv4Addr(bytes)
    }

    /// Gets the bytes of the IPv4 address.
    #[inline]
    pub const fn ipv4_bytes(self) -> [u8; 4] {
        self.0
    }

    /// Is this the limited broadcast address?
    ///
    /// `is_limited_broadcast` is a shorthand for comparing against
    /// [`Ipv4::LIMITED_BROADCAST_ADDRESS`].
    #[inline]
    pub fn is_limited_broadcast(self) -> bool {
        self == Ipv4::LIMITED_BROADCAST_ADDRESS.get()
    }

    /// Is this a Class E address?
    ///
    /// `is_class_e` is a shorthand for checking membership in
    /// [`Ipv4::CLASS_E_SUBNET`].
    #[inline]
    pub fn is_class_e(self) -> bool {
        Ipv4::CLASS_E_SUBNET.contains(&self)
    }

    /// Converts the address to an IPv4-compatible IPv6 address according to
    /// [RFC 4291 Section 2.5.5.1].
    ///
    /// IPv4-compatible IPv6 addresses were defined to assist in the IPv6
    /// transition, and are now specified in [RFC 4291 Section 2.5.5.1]. The
    /// lowest-order 32 bits carry an IPv4 address, while the highest-order 96
    /// bits are all set to 0 as in this diagram from the RFC:
    ///
    /// ```text
    /// |                80 bits               | 16 |      32 bits        |
    /// +--------------------------------------+--------------------------+
    /// |0000..............................0000|0000|    IPv4 address     |
    /// +--------------------------------------+----+---------------------+
    /// ```
    ///
    /// Per RFC 4291:
    ///
    /// > The 'IPv4-Compatible IPv6 address' is now deprecated because the
    /// > current IPv6 transition mechanisms no longer use these addresses. New
    /// > or updated implementations are not required to support this address
    /// > type.
    ///
    /// The more modern embedding format is IPv4-mapped IPv6 addressing - see
    /// [`to_ipv6_mapped`].
    ///
    /// [RFC 4291 Section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
    /// [`to_ipv6_mapped`]: Ipv4Addr::to_ipv6_mapped
    #[inline]
    pub fn to_ipv6_compatible(self) -> Ipv6Addr {
        let Self([a, b, c, d]) = self;
        Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
    }

    /// Converts the address to an IPv4-mapped IPv6 address according to [RFC
    /// 4291 Section 2.5.5.2].
    ///
    /// IPv4-mapped IPv6 addresses are used to represent the addresses of IPv4
    /// nodes as IPv6 addresses, and are defined in [RFC 4291 Section 2.5.5.2].
    /// The lowest-order 32 bits carry an IPv4 address, the middle order 16 bits
    /// carry the literal 0xFFFF, and the highest order 80 bits are set to 0 as
    /// in this diagram from the RFC:
    ///
    /// ```text
    /// |                80 bits               | 16 |      32 bits        |
    /// +--------------------------------------+--------------------------+
    /// |0000..............................0000|FFFF|    IPv4 address     |
    /// +--------------------------------------+----+---------------------+
    /// ```
    ///
    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
    #[inline]
    pub fn to_ipv6_mapped(self) -> SpecifiedAddr<Ipv6Addr> {
        let Self([a, b, c, d]) = self;
        SpecifiedAddr::new(Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d]))
            .unwrap()
    }

    /// Returns the address's class according to the obsoleted classful
    /// addressing architecture.
    pub fn class(&self) -> Ipv4AddressClass {
        for (subnet, class) in [
            (Ipv4::CLASS_A_SUBNET, Ipv4AddressClass::A),
            (Ipv4::CLASS_B_SUBNET, Ipv4AddressClass::B),
            (Ipv4::CLASS_C_SUBNET, Ipv4AddressClass::C),
            (Ipv4::CLASS_D_SUBNET, Ipv4AddressClass::D),
            (Ipv4::CLASS_E_SUBNET, Ipv4AddressClass::E),
        ] {
            if subnet.contains(self) {
                return class;
            }
        }

        unreachable!("{} should fit into a class", self)
    }
}

impl sealed::Sealed for Ipv4Addr {}

impl IpAddress for Ipv4Addr {
    const BYTES: u8 = 4;

    type Version = Ipv4;

    #[inline]
    fn mask(&self, bits: u8) -> Self {
        assert!(bits <= 32);
        // Need to perform a checked shift left in case `bits == 32`, in which
        // case an unchecked shift left (`u32::MAX << bits`) would overflow,
        // causing a panic in debug mode.
        let mask = u32::MAX.checked_shl((32 - bits).into()).unwrap_or(0);
        Ipv4Addr((u32::from_be_bytes(self.0) & mask).to_be_bytes())
    }

    #[inline]
    fn bytes(&self) -> &[u8] {
        &self.0
    }

    #[inline]
    fn to_ip_addr(&self) -> IpAddr {
        IpAddr::V4(*self)
    }

    #[inline]
    fn common_prefix_len(&self, other: &Ipv4Addr) -> u8 {
        let me = u32::from_be_bytes(self.0);
        let other = u32::from_be_bytes(other.0);
        // `same_bits` has a 0 wherever `me` and `other` have the same bit in a
        // given position, and a 1 wherever they have opposite bits.
        let same_bits = me ^ other;
        same_bits.leading_zeros() as u8
    }

    #[inline]
    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool {
        !self.is_multicast()
            && !self.is_limited_broadcast()
            // This clause implements the rules that (the subnet broadcast is
            // not unicast AND the address with an all-zeroes host part is not
            // unicast) UNLESS the prefix length is 31 or 32.
            && (subnet.prefix() == 32
            || subnet.prefix() == 31
            || (*self != subnet.broadcast() && *self != subnet.network()))
            && self.is_specified()
            && !self.is_class_e()
            && subnet.contains(self)
    }

    fn subnet_into_either(subnet: Subnet<Ipv4Addr>) -> SubnetEither {
        SubnetEither::V4(subnet)
    }

    #[inline]
    fn array_into_ip_addr<const N: usize>(
        addrs: [Self; N],
    ) -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
        IpAddr::V4(addrs)
    }
}

impl From<[u8; 4]> for Ipv4Addr {
    #[inline]
    fn from(bytes: [u8; 4]) -> Ipv4Addr {
        Ipv4Addr(bytes)
    }
}

#[cfg(feature = "std")]
impl From<net::Ipv4Addr> for Ipv4Addr {
    #[inline]
    fn from(ip: net::Ipv4Addr) -> Ipv4Addr {
        Ipv4Addr::new(ip.octets())
    }
}

#[cfg(feature = "std")]
impl From<Ipv4Addr> for net::Ipv4Addr {
    #[inline]
    fn from(ip: Ipv4Addr) -> net::Ipv4Addr {
        net::Ipv4Addr::from(ip.0)
    }
}

impl Display for Ipv4Addr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        write!(f, "{}.{}.{}.{}", self.0[0], self.0[1], self.0[2], self.0[3])
    }
}

impl Debug for Ipv4Addr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        Display::fmt(self, f)
    }
}

/// An IPv6 address.
///
/// # Layout
///
/// `Ipv6Addr` has the same layout as `[u8; 16]`, which is the layout that most
/// protocols use to represent an IPv6 address in their packet formats. This can
/// be useful when parsing an IPv6 address from a packet. For example:
///
/// ```rust
/// # use net_types::ip::Ipv6Addr;
/// /// The fixed part of an IPv6 packet header.
/// ///
/// /// `FixedHeader` has the same layout as the fixed part of an IPv6 packet
/// /// header.
/// #[repr(C)]
/// pub struct FixedHeader {
///     version_tc_flowlabel: [u8; 4],
///     payload_len: [u8; 2],
///     next_hdr: u8,
///     hop_limit: u8,
///     src_ip: Ipv6Addr,
///     dst_ip: Ipv6Addr,
/// }
/// ```
///
/// # `Display`
///
/// The [`Display`] impl for `Ipv6Addr` formats according to [RFC 5952].
///
/// Where RFC 5952 leaves decisions up to the implementation, `Ipv6Addr` matches
/// the behavior of [`std::net::Ipv6Addr`] - all IPv6 addresses are formatted
/// the same by `Ipv6Addr` as by `<std::net::Ipv6Addr as Display>::fmt`.
///
/// [RFC 5952]: https://datatracker.ietf.org/doc/html/rfc5952
#[derive(
    Copy,
    Clone,
    Default,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    FromZeros,
    FromBytes,
    AsBytes,
    NoCell,
    Unaligned,
)]
#[repr(transparent)]
pub struct Ipv6Addr([u8; 16]);

impl Ipv6Addr {
    /// Creates a new IPv6 address from 16-bit segments.
    #[inline]
    pub const fn new(segments: [u16; 8]) -> Ipv6Addr {
        #![allow(clippy::many_single_char_names)]
        let [a, b, c, d, e, f, g, h] = segments;
        let [aa, ab] = a.to_be_bytes();
        let [ba, bb] = b.to_be_bytes();
        let [ca, cb] = c.to_be_bytes();
        let [da, db] = d.to_be_bytes();
        let [ea, eb] = e.to_be_bytes();
        let [fa, fb] = f.to_be_bytes();
        let [ga, gb] = g.to_be_bytes();
        let [ha, hb] = h.to_be_bytes();
        Ipv6Addr([aa, ab, ba, bb, ca, cb, da, db, ea, eb, fa, fb, ga, gb, ha, hb])
    }

    /// Creates a new IPv6 address from bytes.
    #[inline]
    pub const fn from_bytes(bytes: [u8; 16]) -> Ipv6Addr {
        Ipv6Addr(bytes)
    }

    /// Gets the bytes of the IPv6 address.
    #[inline]
    pub const fn ipv6_bytes(&self) -> [u8; 16] {
        self.0
    }

    /// Gets the 16-bit segments of the IPv6 address.
    #[inline]
    pub fn segments(&self) -> [u16; 8] {
        #![allow(clippy::many_single_char_names)]
        let [a, b, c, d, e, f, g, h]: [zerocopy::network_endian::U16; 8] =
            zerocopy::transmute!(self.ipv6_bytes());
        [a.into(), b.into(), c.into(), d.into(), e.into(), f.into(), g.into(), h.into()]
    }

    /// Converts this `Ipv6Addr` to the IPv6 Solicited-Node Address, used in
    /// Neighbor Discovery, defined in [RFC 4291 Section 2.7.1].
    ///
    /// [RFC 4291 Section 2.7.1]: https://tools.ietf.org/html/rfc4291#section-2.7.1
    #[inline]
    pub const fn to_solicited_node_address(&self) -> MulticastAddr<Ipv6Addr> {
        // TODO(brunodalbo) benchmark this generation and evaluate if using
        //  bit operations with u128 could be faster. This is very likely
        //  going to be on a hot path.

        // We know we are not breaking the guarantee that `MulticastAddr` provides
        // when calling `new_unchecked` because the address we provide it is
        // a multicast address as defined by RFC 4291 section 2.7.1.
        unsafe {
            MulticastAddr::new_unchecked(Ipv6Addr::from_bytes([
                0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, self.0[13], self.0[14],
                self.0[15],
            ]))
        }
    }

    /// Is this a valid unicast address?
    ///
    /// A valid unicast address is any unicast address that can be bound to an
    /// interface (not the unspecified or loopback addresses).
    /// `addr.is_valid_unicast()` is equivalent to `!(addr.is_loopback() ||
    /// !addr.is_specified() || addr.is_multicast())`.
    #[inline]
    pub fn is_valid_unicast(&self) -> bool {
        !(self.is_loopback() || !self.is_specified() || self.is_multicast())
    }

    /// Is this address in the (deprecated) site-local unicast subnet?
    ///
    /// `is_site_local` returns true if `self` is in the (deprecated)
    /// [`Ipv6::SITE_LOCAL_UNICAST_SUBNET`]. See that constant's documentation
    /// for more details on deprecation and how the subnet should be used in
    /// light of deprecation.
    #[inline]
    pub fn is_site_local(&self) -> bool {
        Ipv6::SITE_LOCAL_UNICAST_SUBNET.contains(self)
    }

    /// Is this a unicast link-local address?
    ///
    /// `addr.is_unicast_link_local()` is equivalent to
    /// `addr.is_unicast_in_subnet(&Ipv6::LINK_LOCAL_UNICAST_SUBNET)`.
    #[inline]
    pub fn is_unicast_link_local(&self) -> bool {
        self.is_unicast_in_subnet(&Ipv6::LINK_LOCAL_UNICAST_SUBNET)
    }

    /// Tries to extract the IPv4 address from an IPv4-compatible IPv6 address.
    ///
    /// IPv4-compatible IPv6 addresses were defined to assist in the IPv6
    /// transition, and are now specified in [RFC 4291 Section 2.5.5.1]. The
    /// lowest-order 32 bits carry an IPv4 address, while the highest-order 96
    /// bits are all set to 0 as in this diagram from the RFC:
    ///
    /// ```text
    /// |                80 bits               | 16 |      32 bits        |
    /// +--------------------------------------+--------------------------+
    /// |0000..............................0000|0000|    IPv4 address     |
    /// +--------------------------------------+----+---------------------+
    /// ```
    ///
    /// `to_ipv4_compatible` checks to see if `self` is an IPv4-compatible
    /// IPv6 address. If it is, the IPv4 address is extracted and returned.
    ///
    /// Per RFC 4291:
    ///
    /// > The 'IPv4-Compatible IPv6 address' is now deprecated because the
    /// > current IPv6 transition mechanisms no longer use these addresses. New
    /// > or updated implementations are not required to support this address
    /// > type.
    ///
    /// The more modern embedding format is IPv4-mapped IPv6 addressing - see
    /// [`to_ipv4_mapped`].
    ///
    /// [RFC 4291 Section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1
    /// [`to_ipv4_mapped`]: Ipv6Addr::to_ipv4_mapped
    pub fn to_ipv4_compatible(&self) -> Option<Ipv4Addr> {
        if let [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d] = self.0 {
            Some(Ipv4Addr::new([a, b, c, d]))
        } else {
            None
        }
    }

    /// Tries to extract the IPv4 address from an IPv4-mapped IPv6 address.
    ///
    /// IPv4-mapped IPv6 addresses are used to represent the addresses of IPv4
    /// nodes as IPv6 addresses, and are defined in [RFC 4291 Section 2.5.5.2].
    /// The lowest-order 32 bits carry an IPv4 address, the middle order 16 bits
    /// carry the literal 0xFFFF, and the highest order 80 bits are set to 0 as
    /// in this diagram from the RFC:
    ///
    /// ```text
    /// |                80 bits               | 16 |      32 bits        |
    /// +--------------------------------------+--------------------------+
    /// |0000..............................0000|FFFF|    IPv4 address     |
    /// +--------------------------------------+----+---------------------+
    /// ```
    ///
    /// `to_ipv4_mapped` checks to see if `self` is an IPv4-mapped
    /// IPv6 address. If it is, the IPv4 address is extracted and returned.
    ///
    /// [RFC 4291 Section 2.5.5.2]: https://tools.ietf.org/html/rfc4291#section-2.5.5.2
    pub fn to_ipv4_mapped(&self) -> Option<Ipv4Addr> {
        if let [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d] = self.0 {
            Some(Ipv4Addr::new([a, b, c, d]))
        } else {
            None
        }
    }
}

impl sealed::Sealed for Ipv6Addr {}

/// [`Ipv4Addr`] is convertible into [`Ipv6Addr`] through
/// [`Ipv4Addr::to_ipv6_mapped`].
impl From<Ipv4Addr> for Ipv6Addr {
    fn from(addr: Ipv4Addr) -> Ipv6Addr {
        *addr.to_ipv6_mapped()
    }
}

impl IpAddress for Ipv6Addr {
    const BYTES: u8 = 16;

    type Version = Ipv6;

    #[inline]
    fn mask(&self, bits: u8) -> Ipv6Addr {
        assert!(bits <= 128);
        // Need to perform a checked shift left in case `bits == 128`, in which
        // case an unchecked shift left (`u128::MAX << bits`) would overflow,
        // causing a panic in debug mode.
        let mask = u128::MAX.checked_shl((128 - bits).into()).unwrap_or(0);
        Ipv6Addr((u128::from_be_bytes(self.0) & mask).to_be_bytes())
    }

    #[inline]
    fn bytes(&self) -> &[u8] {
        &self.0
    }

    #[inline]
    fn to_ip_addr(&self) -> IpAddr {
        IpAddr::V6(*self)
    }

    #[inline]
    fn common_prefix_len(&self, other: &Ipv6Addr) -> u8 {
        let me = u128::from_be_bytes(self.0);
        let other = u128::from_be_bytes(other.0);
        // `same_bits` has a 0 wherever `me` and `other` have the same bit in a
        // given position, and a 1 wherever they have opposite bits.
        let same_bits = me ^ other;
        same_bits.leading_zeros() as u8
    }

    #[inline]
    fn is_unicast_in_subnet(&self, subnet: &Subnet<Self>) -> bool {
        !self.is_multicast() && self.is_specified() && subnet.contains(self)
    }

    fn subnet_into_either(subnet: Subnet<Ipv6Addr>) -> SubnetEither {
        SubnetEither::V6(subnet)
    }

    #[inline]
    fn array_into_ip_addr<const N: usize>(
        addrs: [Self; N],
    ) -> IpAddr<[Ipv4Addr; N], [Ipv6Addr; N]> {
        IpAddr::V6(addrs)
    }
}

impl UnicastAddress for Ipv6Addr {
    /// Is this a unicast address?
    ///
    /// `addr.is_unicast()` is equivalent to `!addr.is_multicast() &&
    /// addr.is_specified()`.
    #[inline]
    fn is_unicast(&self) -> bool {
        !self.is_multicast() && self.is_specified()
    }
}

impl From<[u8; 16]> for Ipv6Addr {
    #[inline]
    fn from(bytes: [u8; 16]) -> Ipv6Addr {
        Ipv6Addr::from_bytes(bytes)
    }
}

#[cfg(feature = "std")]
impl From<net::Ipv6Addr> for Ipv6Addr {
    #[inline]
    fn from(addr: net::Ipv6Addr) -> Ipv6Addr {
        Ipv6Addr::from_bytes(addr.octets())
    }
}

#[cfg(feature = "std")]
impl From<Ipv6Addr> for net::Ipv6Addr {
    #[inline]
    fn from(addr: Ipv6Addr) -> net::Ipv6Addr {
        net::Ipv6Addr::from(addr.ipv6_bytes())
    }
}

impl Display for Ipv6Addr {
    /// Formats an IPv6 address according to [RFC 5952].
    ///
    /// Where RFC 5952 leaves decisions up to the implementation, this function
    /// matches the behavior of [`std::net::Ipv6Addr`] - all IPv6 addresses are
    /// formatted the same by this function as by `<std::net::Ipv6Addr as
    /// Display>::fmt`.
    ///
    /// [RFC 5952]: https://datatracker.ietf.org/doc/html/rfc5952
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        // `fmt_inner` implements the core of the formatting algorithm, but does
        // not handle precision or width requirements. Those are handled below
        // by creating a scratch buffer, calling `fmt_inner` on that scratch
        // buffer, and then satisfying those requirements.
        fn fmt_inner<W: fmt::Write>(addr: &Ipv6Addr, w: &mut W) -> Result<(), fmt::Error> {
            // We special-case the unspecified address, localhost address, and
            // IPv4-mapped addresses, but not IPv4-compatible addresses. We
            // follow Rust's behavior here: https://github.com/rust-lang/rust/pull/112606
            if !addr.is_specified() {
                write!(w, "::")
            } else if addr.is_loopback() {
                write!(w, "::1")
            } else if let Some(v4) = addr.to_ipv4_mapped() {
                write!(w, "::ffff:{}", v4)
            } else {
                let segments = addr.segments();

                let longest_zero_span = {
                    let mut longest_zero_span = 0..0;
                    let mut current_zero_span = 0..0;
                    for (i, seg) in segments.iter().enumerate() {
                        if *seg == 0 {
                            current_zero_span.end = i + 1;
                            if current_zero_span.len() > longest_zero_span.len() {
                                longest_zero_span = current_zero_span.clone();
                            }
                        } else {
                            let next_idx = i + 1;
                            current_zero_span = next_idx..next_idx;
                        }
                    }
                    longest_zero_span
                };

                let write_slice = |w: &mut W, slice: &[u16]| {
                    if let [head, tail @ ..] = slice {
                        write!(w, "{:x}", head)?;
                        for seg in tail {
                            write!(w, ":{:x}", seg)?;
                        }
                    }
                    Ok(())
                };

                // Note that RFC 5952 gives us a choice of when to compress a
                // run of zeroes:
                //
                //   It is possible to select whether or not to omit just one
                //   16-bit 0 field.
                //
                // Given this choice, we opt to match the stdlib's behavior.
                // This makes it easier to write tests (we can simply check to
                // see whether our behavior matches `std`'s behavior on a range
                // of inputs), and makes it so that our `Ipv6Addr` type is,
                // behaviorally, more of a drop-in for `std::net::Ipv6Addr` than
                // it would be if we were to diverge on formatting. This makes
                // replacing `std::net::Ipv6Addr` with our `Ipv6Addr` easier for
                // clients, and also makes it an easier choice since they don't
                // have to weigh whether the difference in behavior is
                // acceptable for them.
                if longest_zero_span.len() > 1 {
                    write_slice(w, &segments[..longest_zero_span.start])?;
                    w.write_str("::")?;
                    write_slice(w, &segments[longest_zero_span.end..])
                } else {
                    write_slice(w, &segments)
                }
            }
        }

        if f.precision().is_none() && f.width().is_none() {
            // Fast path: No precision or width requirements, so write directly
            // to `f`.
            fmt_inner(self, f)
        } else {
            // Slow path: Precision or width requirement(s), so construct a
            // scratch buffer, use the `fmt_inner` to fill it, then use `f.pad`
            // to satisfy precision/width requirement(s).

            // `[u8]` does not implement `core::fmt::Write`, so we provide our
            // own wrapper which does.
            struct ByteSlice<'a>(&'a mut [u8]);

            impl<'a> fmt::Write for ByteSlice<'a> {
                fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> {
                    let from = s.as_bytes();

                    if from.len() > self.0.len() {
                        return Err(fmt::Error);
                    }

                    // Temporarily replace `self.0` with an empty slice and move
                    // the old value of `self.0` into our scope so that we can
                    // operate on it by value. This allows us to split it in two
                    // (`to` and `remaining`) and then overwrite `self.0` with
                    // `remaining`.
                    let to = mem::replace(&mut self.0, &mut [][..]);
                    let (to, remaining) = to.split_at_mut(from.len());
                    to.copy_from_slice(from);

                    self.0 = remaining;
                    Ok(())
                }
            }

            // The maximum length for an IPv6 address displays all 8 pairs of
            // bytes in hexadecimal representation (4 characters per two bytes
            // of IPv6 address), each separated with colons (7 colons total).
            const MAX_DISPLAY_LEN: usize = (4 * 8) + 7;
            let mut scratch = [0u8; MAX_DISPLAY_LEN];
            let mut scratch_slice = ByteSlice(&mut scratch[..]);
            // `fmt_inner` only returns an error if a method on `w` returns an
            // error. Since, in this call to `fmt_inner`, `w` is
            // `scratch_slice`, the only error that could happen would be if we
            // run out of space, but we know we won't because `scratch_slice`
            // has `MAX_DISPLAY_LEN` bytes, which is enough to hold any
            // formatted IPv6 address.
            fmt_inner(self, &mut scratch_slice)
                .expect("<Ipv6Addr as Display>::fmt: fmt_inner should have succeeded because the scratch buffer was long enough");
            let unwritten = scratch_slice.0.len();
            let len = MAX_DISPLAY_LEN - unwritten;
            // `fmt_inner` only writes valid UTF-8.
            let str = core::str::from_utf8(&scratch[..len])
                .expect("<Ipv6Addr as Display>::fmt: scratch buffer should contain valid UTF-8");
            f.pad(str)
        }
    }
}

impl Debug for Ipv6Addr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        Display::fmt(self, f)
    }
}

/// The source address from an IPv6 packet.
///
/// An `Ipv6SourceAddr` represents the source address from an IPv6 packet, which
/// may only be either:
///   * unicast and non-mapped (e.g. not an ipv4-mapped-ipv6 address), or
///   * unspecified.
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Ipv6SourceAddr {
    Unicast(NonMappedAddr<UnicastAddr<Ipv6Addr>>),
    Unspecified,
}

impl crate::sealed::Sealed for Ipv6SourceAddr {}

impl Ipv6SourceAddr {
    /// Constructs a new `Ipv6SourceAddr`.
    ///
    /// Returns `None` if `addr` does not satisfy the properties required of an
    /// `Ipv6SourceAddr`.
    #[inline]
    pub fn new(addr: Ipv6Addr) -> Option<Ipv6SourceAddr> {
        if let Some(addr) = UnicastAddr::new(addr) {
            NonMappedAddr::new(addr).map(Ipv6SourceAddr::Unicast)
        } else if !addr.is_specified() {
            Some(Ipv6SourceAddr::Unspecified)
        } else {
            None
        }
    }
}

impl Witness<Ipv6Addr> for Ipv6SourceAddr {
    #[inline]
    fn new(addr: Ipv6Addr) -> Option<Ipv6SourceAddr> {
        Ipv6SourceAddr::new(addr)
    }

    #[inline]
    unsafe fn new_unchecked(addr: Ipv6Addr) -> Ipv6SourceAddr {
        Ipv6SourceAddr::new(addr).unwrap()
    }

    #[inline]
    fn into_addr(self) -> Ipv6Addr {
        match self {
            Ipv6SourceAddr::Unicast(addr) => **addr,
            Ipv6SourceAddr::Unspecified => Ipv6::UNSPECIFIED_ADDRESS,
        }
    }
}

impl SpecifiedAddress for Ipv6SourceAddr {
    fn is_specified(&self) -> bool {
        self != &Ipv6SourceAddr::Unspecified
    }
}

impl UnicastAddress for Ipv6SourceAddr {
    fn is_unicast(&self) -> bool {
        matches!(self, Ipv6SourceAddr::Unicast(_))
    }
}

impl LinkLocalAddress for Ipv6SourceAddr {
    fn is_link_local(&self) -> bool {
        let addr: Ipv6Addr = self.into();
        addr.is_link_local()
    }
}

impl MappedAddress for Ipv6SourceAddr {
    fn is_non_mapped(&self) -> bool {
        let addr: Ipv6Addr = self.into();
        addr.is_non_mapped()
    }
}

impl From<Ipv6SourceAddr> for Ipv6Addr {
    fn from(addr: Ipv6SourceAddr) -> Ipv6Addr {
        addr.get()
    }
}

impl From<&'_ Ipv6SourceAddr> for Ipv6Addr {
    fn from(addr: &Ipv6SourceAddr) -> Ipv6Addr {
        match addr {
            Ipv6SourceAddr::Unicast(addr) => addr.get(),
            Ipv6SourceAddr::Unspecified => Ipv6::UNSPECIFIED_ADDRESS,
        }
    }
}

impl TryFrom<Ipv6Addr> for Ipv6SourceAddr {
    type Error = ();
    fn try_from(addr: Ipv6Addr) -> Result<Ipv6SourceAddr, ()> {
        Ipv6SourceAddr::new(addr).ok_or(())
    }
}

impl AsRef<Ipv6Addr> for Ipv6SourceAddr {
    fn as_ref(&self) -> &Ipv6Addr {
        match self {
            Ipv6SourceAddr::Unicast(addr) => addr,
            Ipv6SourceAddr::Unspecified => &Ipv6::UNSPECIFIED_ADDRESS,
        }
    }
}

impl Deref for Ipv6SourceAddr {
    type Target = Ipv6Addr;

    fn deref(&self) -> &Ipv6Addr {
        self.as_ref()
    }
}

impl Display for Ipv6SourceAddr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        match self {
            Ipv6SourceAddr::Unicast(addr) => write!(f, "{}", addr),
            Ipv6SourceAddr::Unspecified => write!(f, "::"),
        }
    }
}

impl Debug for Ipv6SourceAddr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        Display::fmt(self, f)
    }
}

/// An IPv6 address stored as a unicast or multicast witness type.
///
/// `UnicastOrMulticastIpv6Addr` is either a [`UnicastAddr`] or a
/// [`MulticastAddr`]. It allows the user to match on the unicast-ness or
/// multicast-ness of an IPv6 address and obtain a statically-typed witness in
/// each case. This is useful if the user needs to call different functions
/// which each take a witness type.
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum UnicastOrMulticastIpv6Addr {
    Unicast(UnicastAddr<Ipv6Addr>),
    Multicast(MulticastAddr<Ipv6Addr>),
}

impl UnicastOrMulticastIpv6Addr {
    /// Constructs a new `UnicastOrMulticastIpv6Addr`.
    ///
    /// Returns `None` if `addr` is the unspecified address.
    pub fn new(addr: Ipv6Addr) -> Option<UnicastOrMulticastIpv6Addr> {
        SpecifiedAddr::new(addr).map(UnicastOrMulticastIpv6Addr::from_specified)
    }

    /// Constructs a new `UnicastOrMulticastIpv6Addr` from a specified address.
    pub fn from_specified(addr: SpecifiedAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
        if addr.is_unicast() {
            UnicastOrMulticastIpv6Addr::Unicast(UnicastAddr(addr.get()))
        } else {
            UnicastOrMulticastIpv6Addr::Multicast(MulticastAddr(addr.get()))
        }
    }
}

impl crate::sealed::Sealed for UnicastOrMulticastIpv6Addr {}

impl Witness<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
    #[inline]
    fn new(addr: Ipv6Addr) -> Option<UnicastOrMulticastIpv6Addr> {
        UnicastOrMulticastIpv6Addr::new(addr)
    }

    #[inline]
    unsafe fn new_unchecked(addr: Ipv6Addr) -> UnicastOrMulticastIpv6Addr {
        UnicastOrMulticastIpv6Addr::new(addr).unwrap()
    }

    #[inline]
    fn into_addr(self) -> Ipv6Addr {
        match self {
            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.get(),
            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.get(),
        }
    }
}

impl UnicastAddress for UnicastOrMulticastIpv6Addr {
    fn is_unicast(&self) -> bool {
        matches!(self, UnicastOrMulticastIpv6Addr::Unicast(_))
    }
}

impl MulticastAddress for UnicastOrMulticastIpv6Addr {
    fn is_multicast(&self) -> bool {
        matches!(self, UnicastOrMulticastIpv6Addr::Multicast(_))
    }
}

impl LinkLocalAddress for UnicastOrMulticastIpv6Addr {
    fn is_link_local(&self) -> bool {
        match self {
            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.is_link_local(),
            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.is_link_local(),
        }
    }
}

impl MappedAddress for UnicastOrMulticastIpv6Addr {
    fn is_non_mapped(&self) -> bool {
        match self {
            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr.is_non_mapped(),
            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr.is_non_mapped(),
        }
    }
}

impl From<UnicastOrMulticastIpv6Addr> for Ipv6Addr {
    fn from(addr: UnicastOrMulticastIpv6Addr) -> Ipv6Addr {
        addr.get()
    }
}

impl From<&'_ UnicastOrMulticastIpv6Addr> for Ipv6Addr {
    fn from(addr: &UnicastOrMulticastIpv6Addr) -> Ipv6Addr {
        addr.get()
    }
}

impl From<UnicastAddr<Ipv6Addr>> for UnicastOrMulticastIpv6Addr {
    fn from(addr: UnicastAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
        UnicastOrMulticastIpv6Addr::Unicast(addr)
    }
}

impl From<MulticastAddr<Ipv6Addr>> for UnicastOrMulticastIpv6Addr {
    fn from(addr: MulticastAddr<Ipv6Addr>) -> UnicastOrMulticastIpv6Addr {
        UnicastOrMulticastIpv6Addr::Multicast(addr)
    }
}

impl TryFrom<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
    type Error = ();
    fn try_from(addr: Ipv6Addr) -> Result<UnicastOrMulticastIpv6Addr, ()> {
        UnicastOrMulticastIpv6Addr::new(addr).ok_or(())
    }
}

impl AsRef<Ipv6Addr> for UnicastOrMulticastIpv6Addr {
    fn as_ref(&self) -> &Ipv6Addr {
        match self {
            UnicastOrMulticastIpv6Addr::Unicast(addr) => addr,
            UnicastOrMulticastIpv6Addr::Multicast(addr) => addr,
        }
    }
}

impl Deref for UnicastOrMulticastIpv6Addr {
    type Target = Ipv6Addr;

    fn deref(&self) -> &Ipv6Addr {
        self.as_ref()
    }
}

impl Display for UnicastOrMulticastIpv6Addr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        match self {
            UnicastOrMulticastIpv6Addr::Unicast(addr) => write!(f, "{}", addr),
            UnicastOrMulticastIpv6Addr::Multicast(addr) => write!(f, "{}", addr),
        }
    }
}

impl Debug for UnicastOrMulticastIpv6Addr {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        Display::fmt(self, f)
    }
}

/// The error returned from [`Subnet::new`] and [`SubnetEither::new`].
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum SubnetError {
    /// The network prefix is longer than the number of bits in the address (32
    /// for IPv4/128 for IPv6).
    PrefixTooLong,
    /// The network address has some bits in the host part (past the network
    /// prefix) set to one.
    HostBitsSet,
}

/// A prefix was provided which is longer than the number of bits in the address
/// (32 for IPv4/128 for IPv6).
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct PrefixTooLongError;

/// An IP subnet.
///
/// `Subnet` is a combination of an IP network address and a prefix length.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Subnet<A> {
    // invariant: only contains prefix bits
    network: A,
    prefix: u8,
}

impl<A: core::cmp::Ord> core::cmp::PartialOrd for Subnet<A> {
    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

/// Subnet ordering always orders from least-specific to most-specific subnet.
impl<A: core::cmp::Ord> core::cmp::Ord for Subnet<A> {
    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
        let Self { network, prefix } = self;
        let Self { network: other_network, prefix: other_prefix } = other;
        match prefix.cmp(other_prefix) {
            core::cmp::Ordering::Equal => network.cmp(other_network),
            ord => ord,
        }
    }
}

impl<A> Subnet<A> {
    /// Creates a new subnet without enforcing correctness.
    ///
    /// # Safety
    ///
    /// Unlike `new`, `new_unchecked` does not validate that `prefix` is in the
    /// proper range, and does not check that `network` has only the top
    /// `prefix` bits set. It is up to the caller to guarantee that `prefix` is
    /// in the proper range, and that none of the bits of `network` beyond the
    /// prefix are set.
    #[inline]
    pub const unsafe fn new_unchecked(network: A, prefix: u8) -> Subnet<A> {
        Subnet { network, prefix }
    }
}

impl<A: IpAddress> Subnet<A> {
    /// Creates a new subnet.
    ///
    /// `new` creates a new subnet with the given network address and prefix
    /// length. It returns `Err` if `prefix` is longer than the number of bits
    /// in this type of IP address (32 for IPv4 and 128 for IPv6) or if any of
    /// the host bits (beyond the first `prefix` bits) are set in `network`.
    #[inline]
    pub fn new(network: A, prefix: u8) -> Result<Subnet<A>, SubnetError> {
        if prefix > A::BYTES * 8 {
            return Err(SubnetError::PrefixTooLong);
        }
        // TODO(joshlf): Is there a more efficient way we can perform this
        // check?
        if network != network.mask(prefix) {
            return Err(SubnetError::HostBitsSet);
        }
        Ok(Subnet { network, prefix })
    }

    /// Creates a new subnet from the address of a host in that subnet.
    ///
    /// Unlike [`new`], the `host` address may have host bits set.
    ///
    /// [`new`]: Subnet::new
    #[inline]
    pub fn from_host(host: A, prefix: u8) -> Result<Subnet<A>, PrefixTooLongError> {
        if prefix > A::BYTES * 8 {
            return Err(PrefixTooLongError);
        }
        let network = host.mask(prefix);
        Ok(Subnet { network, prefix })
    }

    /// Gets the network address component of this subnet.
    ///
    /// Any bits beyond the prefix will be zero.
    #[inline]
    pub fn network(&self) -> A {
        self.network
    }

    /// Gets the prefix length component of this subnet.
    #[inline]
    pub fn prefix(&self) -> u8 {
        self.prefix
    }

    /// Tests whether an address is in this subnet.
    ///
    /// Tests whether `addr` is in this subnet by testing whether the prefix
    /// bits match the prefix bits of the subnet's network address. This is
    /// equivalent to `sub.network() == addr.mask(sub.prefix())`.
    #[inline]
    pub fn contains(&self, addr: &A) -> bool {
        self.network == addr.mask(self.prefix)
    }
}

impl Subnet<Ipv4Addr> {
    // TODO(joshlf): If we introduce a separate type for an address in a subnet
    // (with fewer requirements than `AddrSubnet` has now so that a broadcast
    // address is representable), then that type could implement
    // `BroadcastAddress`, and `broadcast` could return
    // `BroadcastAddr<Foo<Ipv4Addr>>`.

    /// Gets the broadcast address in this IPv4 subnet.
    #[inline]
    pub fn broadcast(self) -> Ipv4Addr {
        if self.prefix == 32 {
            // shifting right by the size of the value is undefined
            self.network
        } else {
            let mask = <u32>::max_value() >> self.prefix;
            Ipv4Addr::new((u32::from_be_bytes(self.network.0) | mask).to_be_bytes())
        }
    }
}

impl<A: IpAddress> Display for Subnet<A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        write!(f, "{}/{}", self.network, self.prefix)
    }
}

impl<A: IpAddress> Debug for Subnet<A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        write!(f, "{}/{}", self.network, self.prefix)
    }
}

impl<A, I: Ip> GenericOverIp<I> for Subnet<A> {
    type Type = Subnet<I::Addr>;
}

/// An IPv4 subnet or an IPv6 subnet.
///
/// `SubnetEither` is an enum of [`Subnet<Ipv4Addr>`] and `Subnet<Ipv6Addr>`.
///
/// [`Subnet<Ipv4Addr>`]: Subnet
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum SubnetEither {
    V4(Subnet<Ipv4Addr>),
    V6(Subnet<Ipv6Addr>),
}

impl SubnetEither {
    /// Creates a new subnet.
    ///
    /// `new` creates a new subnet with the given network address and prefix
    /// length. It returns `Err` if `prefix` is longer than the number of bits
    /// in this type of IP address (32 for IPv4 and 128 for IPv6) or if any of
    /// the host bits (beyond the first `prefix` bits) are set in `network`.
    #[inline]
    pub fn new(network: IpAddr, prefix: u8) -> Result<SubnetEither, SubnetError> {
        Ok(match network {
            IpAddr::V4(network) => SubnetEither::V4(Subnet::new(network, prefix)?),
            IpAddr::V6(network) => SubnetEither::V6(Subnet::new(network, prefix)?),
        })
    }

    /// Creates a new subnet from the address of a host in that subnet.
    ///
    /// Unlike [`new`], the `host` address may have host bits set.
    ///
    /// [`new`]: SubnetEither::new
    #[inline]
    pub fn from_host(host: IpAddr, prefix: u8) -> Result<SubnetEither, PrefixTooLongError> {
        Ok(match host {
            IpAddr::V4(host) => SubnetEither::V4(Subnet::from_host(host, prefix)?),
            IpAddr::V6(host) => SubnetEither::V6(Subnet::from_host(host, prefix)?),
        })
    }

    /// Gets the network and prefix.
    #[inline]
    pub fn net_prefix(&self) -> (IpAddr, u8) {
        match self {
            SubnetEither::V4(v4) => (v4.network.into(), v4.prefix),
            SubnetEither::V6(v6) => (v6.network.into(), v6.prefix),
        }
    }
}

impl<A: IpAddress> From<Subnet<A>> for SubnetEither {
    fn from(subnet: Subnet<A>) -> SubnetEither {
        A::subnet_into_either(subnet)
    }
}

/// The error returned from [`AddrSubnet::new`] and [`AddrSubnetEither::new`].
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum AddrSubnetError {
    /// The network prefix is longer than the number of bits in the address (32
    /// for IPv4/128 for IPv6).
    PrefixTooLong,
    /// The address is not a unicast address in the given subnet (see
    /// [`IpAddress::is_unicast_in_subnet`]).
    NotUnicastInSubnet,
    /// The address does not satisfy the requirements of the witness type.
    InvalidWitness,
}

// TODO(joshlf): Is the unicast restriction always necessary, or will some users
// want the AddrSubnet functionality without that restriction?

/// An address and that address's subnet.
///
/// An `AddrSubnet` is a pair of an address and a subnet which maintains the
/// invariant that the address is guaranteed to be a unicast address in the
/// subnet. `S` is the type of address ([`Ipv4Addr`] or [`Ipv6Addr`]), and `A`
/// is the type of the address in the subnet, which is always a witness wrapper
/// around `S`. By default, it is `SpecifiedAddr<S>`.
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub struct AddrSubnet<S: IpAddress, A: Witness<S> + Copy = SpecifiedAddr<S>> {
    // TODO(joshlf): Would it be more performant to store these as just an
    // address and subnet mask? It would make the object smaller and so cheaper
    // to pass around, but it would make certain operations more expensive.
    addr: A,
    subnet: Subnet<S>,
}

impl<S: IpAddress, A: Witness<S> + Copy> AddrSubnet<S, A> {
    /// Creates a new `AddrSubnet`.
    ///
    /// `new` is like [`from_witness`], except that it also converts `addr` into
    /// the appropriate witness type, returning
    /// [`AddrSubnetError::InvalidWitness`] if the conversion fails.
    ///
    /// [`from_witness`]: Witness::from_witness
    #[inline]
    pub fn new(addr: S, prefix: u8) -> Result<AddrSubnet<S, A>, AddrSubnetError> {
        AddrSubnet::from_witness(A::new(addr).ok_or(AddrSubnetError::InvalidWitness)?, prefix)
    }

    /// Creates a new `AddrSubnet` without checking for validity.
    ///
    /// # Safety
    ///
    /// Unlike [`new`], `new_unchecked` does not validate that `prefix` is in the
    /// proper range, and does not check that `addr` is a valid value for the
    /// witness type `A`. It is up to the caller to guarantee that `prefix` is
    /// in the proper range, and `A::new(addr)` is not `None`.
    ///
    /// [`new`]: AddrSubnet::new
    #[inline]
    pub unsafe fn new_unchecked(addr: S, prefix: u8) -> Self {
        let (subnet, addr) =
            unsafe { (Subnet::new_unchecked(addr.mask(prefix), prefix), A::new_unchecked(addr)) };
        AddrSubnet { addr, subnet }
    }

    /// Creates a new `AddrSubnet` from an existing witness.
    ///
    /// `from_witness` creates a new `AddrSubnet` with the given address and
    /// prefix length. The network address of the subnet is taken to be the
    /// first `prefix` bits of the address. It returns `Err` if `prefix` is
    /// longer than the number of bits in this type of IP address (32 for IPv4
    /// and 128 for IPv6) or if `addr` is not a unicast address in the resulting
    /// subnet (see [`IpAddress::is_unicast_in_subnet`]).
    pub fn from_witness(addr: A, prefix: u8) -> Result<AddrSubnet<S, A>, AddrSubnetError> {
        if prefix > S::BYTES * 8 {
            return Err(AddrSubnetError::PrefixTooLong);
        }
        let subnet = Subnet { network: addr.as_ref().mask(prefix), prefix };
        if !addr.as_ref().is_unicast_in_subnet(&subnet) {
            return Err(AddrSubnetError::NotUnicastInSubnet);
        }
        Ok(AddrSubnet { addr, subnet })
    }

    /// Gets the subnet.
    #[inline]
    pub fn subnet(&self) -> Subnet<S> {
        self.subnet
    }

    /// Gets the address.
    #[inline]
    pub fn addr(&self) -> A {
        self.addr
    }

    /// Gets the address and subnet.
    #[inline]
    pub fn addr_subnet(self) -> (A, Subnet<S>) {
        (self.addr, self.subnet)
    }

    /// Constructs a new `AddrSubnet` of a different witness type.
    #[inline]
    pub fn to_witness<B: Witness<S> + Copy>(&self) -> AddrSubnet<S, B>
    where
        A: Into<B>,
    {
        AddrSubnet { addr: self.addr.into(), subnet: self.subnet }
    }

    /// Wraps an additional witness onto this [`AddrSubnet`].
    #[inline]
    pub fn add_witness<B: Witness<A> + Witness<S> + Copy>(&self) -> Option<AddrSubnet<S, B>> {
        let addr = B::new(self.addr)?;
        Some(AddrSubnet { addr, subnet: self.subnet })
    }

    /// Replaces the [`AddrSubnet`] witness.
    #[inline]
    pub fn replace_witness<B: Witness<S> + Copy>(&self) -> Option<AddrSubnet<S, B>> {
        let addr = B::new(self.addr.get())?;
        Some(AddrSubnet { addr, subnet: self.subnet })
    }
}

impl<S: IpAddress, A: Witness<S> + Copy + Display> Display for AddrSubnet<S, A> {
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        write!(f, "{}/{}", self.addr, self.subnet.prefix)
    }
}

impl<A: Witness<Ipv6Addr> + Copy> AddrSubnet<Ipv6Addr, A> {
    /// Gets the address as a [`UnicastAddr`] witness.
    ///
    /// Since one of the invariants on an `AddrSubnet` is that its contained
    /// address is unicast in its subnet, `ipv6_unicast_addr` can infallibly
    /// convert its stored address to a `UnicastAddr`.
    pub fn ipv6_unicast_addr(&self) -> UnicastAddr<Ipv6Addr> {
        unsafe { UnicastAddr::new_unchecked(self.addr.get()) }
    }

    /// Constructs a new `AddrSubnet` which stores a [`UnicastAddr`] witness.
    ///
    /// Since one of the invariants on an `AddrSubnet` is that its contained
    /// address is unicast in its subnet, `to_unicast` can infallibly convert
    /// its stored address to a `UnicastAddr`.
    pub fn to_unicast(&self) -> AddrSubnet<Ipv6Addr, UnicastAddr<Ipv6Addr>> {
        let AddrSubnet { addr, subnet } = *self;
        let addr = unsafe { UnicastAddr::new_unchecked(addr.get()) };
        AddrSubnet { addr, subnet }
    }
}

/// An IP prefix length.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, GenericOverIp)]
#[generic_over_ip(I, Ip)]
pub struct PrefixLength<I: Ip> {
    /// `inner` is guaranteed to be a valid prefix length for `I::Addr`.
    inner: u8,
    _ip: IpVersionMarker<I>,
}

impl<I: Ip> PrefixLength<I> {
    /// Returns the prefix length.
    ///
    /// The returned length is guaranteed to be a valid prefix length for
    /// `I::Addr`.
    pub const fn get(self) -> u8 {
        let Self { inner, _ip } = self;
        inner
    }

    /// Gets the subnet-mask representation of this prefix length.
    pub fn get_mask(self) -> I::Addr {
        I::map_ip(
            self,
            |prefix_len| Ipv4::LIMITED_BROADCAST_ADDRESS.mask(prefix_len.get()),
            |prefix_len| Ipv6Addr([u8::MAX; 16]).mask(prefix_len.get()),
        )
    }

    /// Constructs a `PrefixLength` from a given prefix length without checking
    /// whether it is too long for the address type.
    ///
    /// # Safety
    /// `prefix_length` must be less than or equal to the number of bits in
    /// `I::Addr`. In other words, `prefix_length <= I::Addr::BYTES * 8`.
    pub const unsafe fn new_unchecked(prefix_length: u8) -> Self {
        Self { inner: prefix_length, _ip: I::VERSION_MARKER }
    }

    /// Constructs a `PrefixLength` from a given unverified prefix length.
    ///
    /// Returns `Err(PrefixTooLongError)` if `prefix_length` is too long for the
    /// address type.
    pub const fn new(prefix_length: u8) -> Result<Self, PrefixTooLongError> {
        if prefix_length > I::Addr::BYTES * 8 {
            return Err(PrefixTooLongError);
        }
        Ok(Self { inner: prefix_length, _ip: I::VERSION_MARKER })
    }

    /// Constructs a `PrefixLength` from an IP address representing a subnet mask.
    ///
    /// Returns `Err(NotSubnetMaskError)` if `subnet_mask` is not a valid subnet
    /// mask.
    pub fn try_from_subnet_mask(subnet_mask: I::Addr) -> Result<Self, NotSubnetMaskError> {
        let IpInvariant((count_ones, leading_ones)) = I::map_ip(
            subnet_mask,
            |subnet_mask| {
                let number = u32::from_be_bytes(subnet_mask.ipv4_bytes());
                IpInvariant((number.count_ones(), number.leading_ones()))
            },
            |subnet_mask| {
                let number = u128::from_be_bytes(subnet_mask.ipv6_bytes());
                IpInvariant((number.count_ones(), number.leading_ones()))
            },
        );

        if leading_ones != count_ones {
            return Err(NotSubnetMaskError);
        }

        Ok(Self {
            inner: u8::try_from(leading_ones)
                .expect("the number of bits in an IP address fits in u8"),
            _ip: IpVersionMarker::default(),
        })
    }
}

impl<I: Ip> From<PrefixLength<I>> for u8 {
    fn from(value: PrefixLength<I>) -> Self {
        value.get()
    }
}

/// An IP address was provided which is not a valid subnet mask (the address
/// has set bits after the first unset bit).
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct NotSubnetMaskError;

/// A type which is witness to some property about an [`IpAddress`], `A`.
///
/// `IpAddressWitness<A>` extends [`Witness`] of the `IpAddress` type `A` by
/// adding an associated type for the type-erased `IpAddr` version of the same
/// witness type. For example, the following implementation is provided for
/// `SpecifiedAddr<A>`:
///
/// ```rust,ignore
/// impl<A: IpAddress> IpAddressWitness<A> for SpecifiedAddr<A> {
///     type IpAddrWitness = SpecifiedAddr<IpAddr>;
/// }
/// ```
pub trait IpAddressWitness<A: IpAddress>: Witness<A> {
    /// The type-erased version of `Self`.
    ///
    /// For example, `SpecifiedAddr<Ipv4Addr>: IpAddressWitness<IpAddrWitness =
    /// SpecifiedAddr<IpAddr>>`.
    type IpAddrWitness: IpAddrWitness + From<Self>;
}

macro_rules! impl_ip_address_witness {
    ($witness:ident) => {
        impl<A: IpAddress> IpAddressWitness<A> for $witness<A> {
            type IpAddrWitness = $witness<IpAddr>;
        }
    };
}

impl_ip_address_witness!(SpecifiedAddr);
impl_ip_address_witness!(MulticastAddr);
impl_ip_address_witness!(LinkLocalAddr);

/// A type which is a witness to some property about an [`IpAddress`].
///
/// `IpAddrWitness` extends [`Witness`] of [`IpAddr`] by adding associated types
/// for the IPv4- and IPv6-specific versions of the same witness type. For
/// example, the following implementation is provided for
/// `SpecifiedAddr<IpAddr>`:
///
/// ```rust,ignore
/// impl IpAddrWitness for SpecifiedAddr<IpAddr> {
///     type V4 = SpecifiedAddr<Ipv4Addr>;
///     type V6 = SpecifiedAddr<Ipv6Addr>;
/// }
/// ```
pub trait IpAddrWitness: Witness<IpAddr> + Into<IpAddr<Self::V4, Self::V6>> + Copy {
    /// The IPv4-specific version of `Self`.
    ///
    /// For example, `SpecifiedAddr<IpAddr>: IpAddrWitness<V4 =
    /// SpecifiedAddr<Ipv4Addr>>`.
    type V4: Witness<Ipv4Addr> + Into<Self> + Copy;

    /// The IPv6-specific version of `Self`.
    ///
    /// For example, `SpecifiedAddr<IpAddr>: IpAddrWitness<V6 =
    /// SpecifiedAddr<Ipv6Addr>>`.
    type V6: Witness<Ipv6Addr> + Into<Self> + Copy;

    // TODO(https://github.com/rust-lang/rust/issues/44491): Remove these
    // functions once implied where bounds make them unnecessary.

    /// Converts an IPv4-specific witness into a general witness.
    fn from_v4(addr: Self::V4) -> Self {
        addr.into()
    }

    /// Converts an IPv6-specific witness into a general witness.
    fn from_v6(addr: Self::V6) -> Self {
        addr.into()
    }
}

macro_rules! impl_ip_addr_witness {
    ($witness:ident) => {
        impl IpAddrWitness for $witness<IpAddr> {
            type V4 = $witness<Ipv4Addr>;
            type V6 = $witness<Ipv6Addr>;
        }
    };
}

impl_ip_addr_witness!(SpecifiedAddr);
impl_ip_addr_witness!(MulticastAddr);
impl_ip_addr_witness!(LinkLocalAddr);

/// An address and that address's subnet, either IPv4 or IPv6.
///
/// `AddrSubnetEither` is an enum of [`AddrSubnet<Ipv4Addr>`] and
/// `AddrSubnet<Ipv6Addr>`.
///
/// [`AddrSubnet<Ipv4Addr>`]: AddrSubnet
#[allow(missing_docs)]
#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
pub enum AddrSubnetEither<A: IpAddrWitness = SpecifiedAddr<IpAddr>> {
    V4(AddrSubnet<Ipv4Addr, A::V4>),
    V6(AddrSubnet<Ipv6Addr, A::V6>),
}

impl<A: IpAddrWitness> AddrSubnetEither<A> {
    /// Creates a new `AddrSubnetEither`.
    ///
    /// `new` creates a new `AddrSubnetEither` with the given address and prefix
    /// length. It returns `Err` under the same conditions as
    /// [`AddrSubnet::new`].
    #[inline]
    pub fn new(addr: IpAddr, prefix: u8) -> Result<AddrSubnetEither<A>, AddrSubnetError> {
        Ok(match addr {
            IpAddr::V4(addr) => AddrSubnetEither::V4(AddrSubnet::new(addr, prefix)?),
            IpAddr::V6(addr) => AddrSubnetEither::V6(AddrSubnet::new(addr, prefix)?),
        })
    }

    /// Creates a new `AddrSubnetEither` from trusted inputs.
    ///
    /// # Safety
    ///
    /// Unlike [`new`], this assumes that the provided address satisfies the
    /// requirements of the witness type `A`, and that `prefix` is not too large
    /// for the IP version of the address in `addr`.
    ///
    /// [`new`]: AddrSubnetEither::new
    #[inline]
    pub unsafe fn new_unchecked(addr: IpAddr, prefix: u8) -> Self {
        match addr {
            IpAddr::V4(addr) => {
                AddrSubnetEither::V4(unsafe { AddrSubnet::new_unchecked(addr, prefix) })
            }
            IpAddr::V6(addr) => {
                AddrSubnetEither::V6(unsafe { AddrSubnet::new_unchecked(addr, prefix) })
            }
        }
    }

    /// Gets the IP address.
    pub fn addr(&self) -> A {
        match self {
            AddrSubnetEither::V4(v4) => v4.addr.into(),
            AddrSubnetEither::V6(v6) => v6.addr.into(),
        }
    }

    /// Gets the IP address and prefix.
    #[inline]
    pub fn addr_prefix(&self) -> (A, u8) {
        match self {
            AddrSubnetEither::V4(v4) => (v4.addr.into(), v4.subnet.prefix),
            AddrSubnetEither::V6(v6) => (v6.addr.into(), v6.subnet.prefix),
        }
    }

    /// Gets the IP address and subnet.
    #[inline]
    pub fn addr_subnet(&self) -> (A, SubnetEither) {
        match self {
            AddrSubnetEither::V4(v4) => (v4.addr.into(), SubnetEither::V4(v4.subnet)),
            AddrSubnetEither::V6(v6) => (v6.addr.into(), SubnetEither::V6(v6.subnet)),
        }
    }
}

impl<S: IpAddress, A: IpAddressWitness<S> + Copy> From<AddrSubnet<S, A>>
    for AddrSubnetEither<A::IpAddrWitness>
{
    #[inline]
    fn from(addr_sub: AddrSubnet<S, A>) -> AddrSubnetEither<A::IpAddrWitness> {
        let (addr, sub) = addr_sub.addr_subnet();
        // This unwrap is safe because:
        // - `addr_sub: AddrSubnet<S, A>`, so we know that `addr` and
        //   `sub.prefix` are valid arguments to `AddrSubnet::new` (which is
        //   what `AddrSubnetEither::new` calls under the hood).
        // - `A::IpAddrWitness` is the same witness type as `A`, but wrapping
        //   `IpAddr` instead of `Ipv4Addr` or `Ipv6Addr`. `addr: A` means that
        //   `addr` satisfies the property witnessed by the witness type `A`,
        //   which is the same property witnessed by `A::IpAddrWitness`. Thus,
        //   we're guaranteed that, when `AddrSubnetEither::new` tries to
        //   construct the witness, it will succeed.
        AddrSubnetEither::new(addr.get().to_ip_addr(), sub.prefix()).unwrap()
    }
}

impl<A> Display for AddrSubnetEither<A>
where
    A: IpAddrWitness,
    A::V4: Display,
    A::V6: Display,
{
    #[inline]
    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
        match self {
            Self::V4(a) => write!(f, "{}", a),
            Self::V6(a) => write!(f, "{}", a),
        }
    }
}

/// Marks types that are generic over IP version.
///
/// This should be implemented by types that contain a generic parameter
/// [`I: Ip`](Ip) or [`A: IpAddress`](IpAddress) to allow them to be used with
/// [`Ip::map_ip`].
///
/// Implementations of this trait should generally be themselves generic over
/// `Ip`. For example:
/// ```
/// struct AddrAndSubnet<I: Ip> {
///   addr: I::Addr,
///   subnet: Subnet<I::Addr>
/// }
///
/// impl <I: Ip, NewIp: Ip> GenericOverIp<NewIp> for AddrAndSubnet<I> {
///   type Type = AddrAndSubnet<NewIp>;
/// }
/// ```
pub trait GenericOverIp<NewIp: Ip> {
    /// The type of `Self` when its IP-generic parameter is replaced with the
    /// type `NewIp`.
    type Type;
}

/// Wrapper type that implements [`GenericOverIp`] with `Type<I: Ip>=Self`.
///
/// This can be used to make a compound type implement `GenericOverIp` with
/// some portion that is invariant over IP version.
pub struct IpInvariant<T>(pub T);

impl<T> IpInvariant<T> {
    /// Consumes the `IpInvariant` and returns the wrapped value.
    pub fn into_inner(self) -> T {
        self.0
    }
}

impl<I: Ip, T> GenericOverIp<I> for IpInvariant<T> {
    type Type = Self;
}

impl<I: Ip> GenericOverIp<I> for core::convert::Infallible {
    type Type = Self;
}

/// A wrapper structure to add an IP version marker to an IP-invariant type.
#[derive(GenericOverIp, Default, Debug, PartialOrd, Ord, Eq, PartialEq, Hash)]
#[generic_over_ip(I, Ip)]
pub struct IpMarked<I: Ip, T> {
    inner: T,
    _marker: IpVersionMarker<I>,
}

impl<I: Ip, T> Deref for IpMarked<I, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}

impl<I: Ip, T> DerefMut for IpMarked<I, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.as_mut()
    }
}
impl<I: Ip, T> AsRef<T> for IpMarked<I, T> {
    fn as_ref(&self) -> &T {
        &self.inner
    }
}

impl<I: Ip, T> AsMut<T> for IpMarked<I, T> {
    fn as_mut(&mut self) -> &mut T {
        &mut self.inner
    }
}

impl<I: Ip, T> IpMarked<I, T> {
    /// Constructs a new `IpMarked` from the provided `T`.
    pub fn new(inner: T) -> Self {
        Self { inner, _marker: IpVersionMarker::<I>::new() }
    }

    /// Consumes the `IpMarked` and returns the contained `T` by value.
    pub fn into_inner(self) -> T {
        let Self { inner, _marker } = self;
        inner
    }

    /// Gets an immutable reference to the underlying `T`.
    pub fn get(&self) -> &T {
        self.as_ref()
    }

    /// Gets an mutable reference to the underlying `T`.
    pub fn get_mut(&mut self) -> &mut T {
        self.as_mut()
    }
}

/// Calls the provided macro with all suffixes of the input.
macro_rules! for_each_tuple_ {
        ( $m:ident !! ) => ( $m! { });
        ( $m:ident !! $h:ident, $($t:ident,)* ) => (
            $m! { $h $($t)* }
            for_each_tuple_! { $m !! $($t,)* }
        );
    }

/// Calls the provided macro with 0-12 type parameters.
macro_rules! for_each_tuple {
    ($m:ident) => {
        for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, }
    };
}

/// Implements GenericOverIp for a tuple with the provided generic parameters.
macro_rules! ip_generic_tuple {
        () => {
            impl<I: Ip> GenericOverIp<I> for () {
                type Type = Self;
            }
        };
        ( $name0:ident $($name:ident)* ) => (
            impl<P: Ip, $name0: GenericOverIp<P>, $($name: GenericOverIp<P>,)*>
            GenericOverIp<P> for ($name0, $($name,)*) {
                type Type = ($name0::Type, $($name::Type,)*);
            }
        );
    }

for_each_tuple!(ip_generic_tuple);

macro_rules! ip_generic {
    ( $type:ident < $($params:ident),* >) => {
        impl<IpType: Ip, $($params: GenericOverIp<IpType>),*>
        GenericOverIp<IpType> for $type<$($params),*> {
            type Type = $type<$($params::Type),*>;
        }
    };
    ( $type:ident) => {
        impl<IpType: Ip> GenericOverIp<IpType> for $type {
            type Type = Self;
        }
    }
}

ip_generic!(Option<T>);
ip_generic!(Result<R, E>);
ip_generic!(bool);
#[cfg(feature = "std")]
ip_generic!(Vec<T>);

impl<'s, NewIp: Ip, T: GenericOverIp<NewIp>> GenericOverIp<NewIp> for &'s T
where
    T::Type: 's,
{
    type Type = &'s T::Type;
}

impl<'s, NewIp: Ip, T: GenericOverIp<NewIp>> GenericOverIp<NewIp> for &'s mut T
where
    T::Type: 's,
{
    type Type = &'s mut T::Type;
}

#[cfg(test)]
mod tests {
    use super::*;
    use test_case::test_case;

    #[test]
    fn test_map_ip_associated_constant() {
        fn get_loopback_address<I: Ip>() -> SpecifiedAddr<I::Addr> {
            I::map_ip((), |()| Ipv4::LOOPBACK_ADDRESS, |()| Ipv6::LOOPBACK_ADDRESS)
        }

        assert_eq!(get_loopback_address::<Ipv4>(), Ipv4::LOOPBACK_ADDRESS);
        assert_eq!(get_loopback_address::<Ipv6>(), Ipv6::LOOPBACK_ADDRESS);
    }

    #[test]
    fn test_map_ip_different_behavior() {
        fn filter_v4<I: Ip>(addr: I::Addr) -> Option<I::Addr> {
            I::map_ip(addr, |addr| Some(addr), |_addr| None)
        }

        assert_eq!(filter_v4::<Ipv4>(*Ipv4::LOOPBACK_ADDRESS), Some(*Ipv4::LOOPBACK_ADDRESS));
        assert_eq!(filter_v4::<Ipv6>(*Ipv6::LOOPBACK_ADDRESS), None);
    }

    #[test]
    fn test_map_ip_extension_trait_fn() {
        trait FakeIpExt: Ip {
            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr;
        }

        impl FakeIpExt for Ipv4 {
            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr {
                let Ipv4Addr(mut bytes) = a;
                bytes.reverse();
                Ipv4Addr(bytes)
            }
        }
        impl FakeIpExt for Ipv6 {
            fn reverse_addr_bytes(a: Self::Addr) -> Self::Addr {
                let Ipv6Addr(mut bytes) = a;
                bytes.reverse();
                Ipv6Addr(bytes)
            }
        }

        fn reverse_bytes<A: IpAddress>(addr: A) -> A
        where
            A::Version: FakeIpExt,
        {
            A::Version::map_ip(addr, Ipv4::reverse_addr_bytes, Ipv6::reverse_addr_bytes)
        }

        assert_eq!(reverse_bytes(Ipv4Addr([1, 2, 3, 4])), Ipv4Addr([4, 3, 2, 1]));
        assert_eq!(
            reverse_bytes(Ipv6Addr([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16])),
            Ipv6Addr([16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
        );
    }

    #[test]
    fn test_map_ip_extension_trait_associated_type() {
        trait FakeIpExt: Ip {
            type PackedInt;
        }
        impl FakeIpExt for Ipv4 {
            type PackedInt = u32;
        }
        impl FakeIpExt for Ipv6 {
            type PackedInt = u128;
        }

        #[derive(Debug, PartialEq)]
        struct Int<T>(T);

        impl<T, I: FakeIpExt> GenericOverIp<I> for Int<T> {
            type Type = Int<I::PackedInt>;
        }

        fn from_be_bytes<A: IpAddress>(addr: A) -> Int<<A::Version as FakeIpExt>::PackedInt>
        where
            A::Version: FakeIpExt,
        {
            A::Version::map_ip(
                addr,
                |Ipv4Addr(bytes)| Int(<Ipv4 as FakeIpExt>::PackedInt::from_be_bytes(bytes)),
                |Ipv6Addr(bytes)| Int(<Ipv6 as FakeIpExt>::PackedInt::from_be_bytes(bytes)),
            )
        }

        assert_eq!(from_be_bytes(Ipv4::LOOPBACK_ADDRESS.get()), Int(0x7f000001u32));
        assert_eq!(from_be_bytes(Ipv6::LOOPBACK_ADDRESS.get()), Int(1u128));
    }

    #[test]
    fn map_ip_twice() {
        struct FooV4 {
            field: Ipv4Addr,
        }

        impl Default for FooV4 {
            fn default() -> Self {
                Self { field: Ipv4::UNSPECIFIED_ADDRESS }
            }
        }

        struct FooV6 {
            field: Ipv6Addr,
        }

        impl Default for FooV6 {
            fn default() -> Self {
                Self { field: Ipv6::UNSPECIFIED_ADDRESS }
            }
        }

        trait IpExt {
            type Foo: Default;
        }

        impl IpExt for Ipv4 {
            type Foo = FooV4;
        }

        impl IpExt for Ipv6 {
            type Foo = FooV6;
        }

        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Foo<I: IpExt>(I::Foo);

        fn do_something<I: Ip + IpExt>(
            foo: Foo<I>,
            extra_foo: Foo<I>,
            captured_foo: Foo<I>,
        ) -> I::Addr {
            let addr: I::Addr = map_ip_twice!(I, foo, |Foo(foo)| { foo.field });

            // Observe that we can use an associated item with `map_ip_twice!
            // too.
            let _: I::Addr =
                map_ip_twice!(<<I as Ip>::Addr as IpAddress>::Version, extra_foo, |Foo(foo)| {
                    // Since `captured_foo` is captured rather than fed through the
                    // generic-over-ip input, this wouldn't work if `I` was aliased
                    // concretely to `Ipv4` or `Ipv6`.
                    let _: &Foo<I> = &captured_foo;
                    foo.field
                });

            addr
        }

        assert_eq!(
            do_something(
                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS }),
                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS }),
                Foo::<Ipv4>(FooV4 { field: Ipv4::UNSPECIFIED_ADDRESS })
            ),
            Ipv4::UNSPECIFIED_ADDRESS
        );
        assert_eq!(
            do_something(
                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS }),
                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS }),
                Foo::<Ipv6>(FooV6 { field: Ipv6::UNSPECIFIED_ADDRESS })
            ),
            Ipv6::UNSPECIFIED_ADDRESS
        );

        fn do_something_with_default_type_alias_shadowing<I: Ip>() -> (I::Addr, IpVersion) {
            let (field, IpInvariant(version)) = map_ip_twice!(I, (), |()| {
                // Note that there's no `IpExt` bound on `I`, so `I` wouldn't
                // work here unless it was automatically aliased to `Ipv4` or `Ipv6`.
                let foo: Foo<I> = Foo(<I as IpExt>::Foo::default());
                (foo.0.field, IpInvariant(I::VERSION))
            },);
            (field, version)
        }

        fn do_something_with_type_alias<I: Ip>() -> (I::Addr, IpVersion) {
            // Show that the type alias inside the macro shadows
            // whatever it was bound to outside the macro.
            #[allow(dead_code)]
            type IpAlias = usize;

            let (field, IpInvariant(version)) = map_ip_twice!(I as IpAlias, (), |()| {
                // Note that there's no `IpExt` bound on `I`, so `I` wouldn't
                // work here -- only `IpAlias`, since `IpAlias` is explicitly
                // an alias of `Ipv4` or `Ipv6`.
                let foo: Foo<IpAlias> = Foo(<IpAlias as IpExt>::Foo::default());
                (foo.0.field, IpInvariant(IpAlias::VERSION))
            },);
            (field, version)
        }

        assert_eq!(
            do_something_with_default_type_alias_shadowing::<Ipv4>(),
            (Ipv4::UNSPECIFIED_ADDRESS, IpVersion::V4)
        );
        assert_eq!(
            do_something_with_default_type_alias_shadowing::<Ipv6>(),
            (Ipv6::UNSPECIFIED_ADDRESS, IpVersion::V6)
        );
        assert_eq!(
            do_something_with_type_alias::<Ipv4>(),
            (Ipv4::UNSPECIFIED_ADDRESS, IpVersion::V4)
        );
        assert_eq!(
            do_something_with_type_alias::<Ipv6>(),
            (Ipv6::UNSPECIFIED_ADDRESS, IpVersion::V6)
        );
    }

    #[test]
    fn test_loopback_unicast() {
        // The loopback addresses are constructed as `SpecifiedAddr`s directly,
        // bypassing the actual check against `is_specified`. Test that that's
        // actually valid.
        assert!(Ipv4::LOOPBACK_ADDRESS.0.is_specified());
        assert!(Ipv6::LOOPBACK_ADDRESS.0.is_specified());
    }

    #[test]
    fn test_specified() {
        // For types that implement SpecifiedAddress,
        // UnicastAddress::is_unicast, MulticastAddress::is_multicast, and
        // LinkLocalAddress::is_link_local all imply
        // SpecifiedAddress::is_specified. Test that that's true for both IPv4
        // and IPv6.

        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_specified());
        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_specified());

        // Unicast

        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_unicast());

        let unicast = Ipv6Addr([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
        assert!(unicast.is_unicast());
        assert!(unicast.is_specified());

        // Multicast

        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_multicast());
        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_multicast());

        let multicast = Ipv4::MULTICAST_SUBNET.network;
        assert!(multicast.is_multicast());
        assert!(multicast.is_specified());
        let multicast = Ipv6::MULTICAST_SUBNET.network;
        assert!(multicast.is_multicast());
        assert!(multicast.is_specified());

        // Link-local

        assert!(!Ipv4::UNSPECIFIED_ADDRESS.is_link_local());
        assert!(!Ipv6::UNSPECIFIED_ADDRESS.is_link_local());

        let link_local = Ipv4::LINK_LOCAL_UNICAST_SUBNET.network;
        assert!(link_local.is_link_local());
        assert!(link_local.is_specified());
        let link_local = Ipv4::LINK_LOCAL_MULTICAST_SUBNET.network;
        assert!(link_local.is_link_local());
        assert!(link_local.is_specified());
        let link_local = Ipv6::LINK_LOCAL_UNICAST_SUBNET.network;
        assert!(link_local.is_link_local());
        assert!(link_local.is_specified());
        let mut link_local = Ipv6::MULTICAST_SUBNET.network;
        link_local.0[1] = 0x02;
        assert!(link_local.is_link_local());
        assert!(link_local.is_specified());
        assert!(Ipv6::LOOPBACK_ADDRESS.is_link_local());
    }

    #[test]
    fn test_link_local() {
        // IPv4
        assert!(Ipv4::LINK_LOCAL_UNICAST_SUBNET.network.is_link_local());
        assert!(Ipv4::LINK_LOCAL_MULTICAST_SUBNET.network.is_link_local());

        // IPv6
        assert!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.is_link_local());
        assert!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.is_unicast_link_local());
        let mut addr = Ipv6::MULTICAST_SUBNET.network;
        for flags in 0..=0x0F {
            // Set the scope to link-local and the flags to `flags`.
            addr.0[1] = (flags << 4) | 0x02;
            // Test that a link-local multicast address is always considered
            // link-local regardless of which flags are set.
            assert!(addr.is_link_local());
            assert!(!addr.is_unicast_link_local());
        }

        // Test that a non-multicast address (outside of the link-local subnet)
        // is never considered link-local even if the bits are set that, in a
        // multicast address, would put it in the link-local scope.
        let mut addr = Ipv6::LOOPBACK_ADDRESS.get();
        // Explicitly set the scope to link-local.
        addr.0[1] = 0x02;
        assert!(!addr.is_link_local());
    }

    #[test]
    fn test_subnet_new() {
        assert_eq!(
            Subnet::new(Ipv4Addr::new([255, 255, 255, 255]), 32).unwrap(),
            Subnet { network: Ipv4Addr::new([255, 255, 255, 255]), prefix: 32 },
        );
        // Prefix exceeds 32 bits
        assert_eq!(
            Subnet::new(Ipv4Addr::new([255, 255, 0, 0]), 33),
            Err(SubnetError::PrefixTooLong)
        );
        assert_eq!(
            Subnet::from_host(Ipv4Addr::new([255, 255, 255, 255]), 33),
            Err(PrefixTooLongError)
        );
        // Network address has more than top 8 bits set
        assert_eq!(Subnet::new(Ipv4Addr::new([255, 255, 0, 0]), 8), Err(SubnetError::HostBitsSet));
        // Host address is allowed to have host bits set
        assert_eq!(
            Subnet::from_host(Ipv4Addr::new([255, 255, 0, 0]), 8),
            Ok(Subnet { network: Ipv4Addr::new([255, 0, 0, 0]), prefix: 8 })
        );

        assert_eq!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32).unwrap(),
            AddrSubnet {
                addr: SpecifiedAddr(Ipv4Addr::new([1, 2, 3, 4])),
                subnet: Subnet { network: Ipv4Addr::new([1, 2, 3, 4]), prefix: 32 }
            }
        );
        // The unspecified address will always fail because it is not valid for
        // the `SpecifiedAddr` witness (use assert, not assert_eq, because
        // AddrSubnet doesn't impl Debug).
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::UNSPECIFIED_ADDRESS, 16)
                == Err(AddrSubnetError::InvalidWitness)
        );
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv6::UNSPECIFIED_ADDRESS, 64)
                == Err(AddrSubnetError::InvalidWitness)
        );
        // Prefix exceeds 32/128 bits
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([1, 2, 3, 4]), 33)
                == Err(AddrSubnetError::PrefixTooLong)
        );
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(
                Ipv6Addr::from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]),
                129,
            ) == Err(AddrSubnetError::PrefixTooLong)
        );
        // Limited broadcast
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4::LIMITED_BROADCAST_ADDRESS.get(), 16)
                == Err(AddrSubnetError::NotUnicastInSubnet)
        );
        // Subnet broadcast
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([192, 168, 255, 255]), 16)
                == Err(AddrSubnetError::NotUnicastInSubnet)
        );
        // Multicast
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(Ipv4Addr::new([224, 0, 0, 1]), 16)
                == Err(AddrSubnetError::NotUnicastInSubnet)
        );
        assert!(
            AddrSubnet::<_, SpecifiedAddr<_>>::new(
                Ipv6Addr::from([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]),
                64,
            ) == Err(AddrSubnetError::NotUnicastInSubnet)
        );

        // If we use the `LinkLocalAddr` witness type, then non link-local
        // addresses are rejected. Note that this address was accepted above
        // when `SpecifiedAddr` was used.
        assert!(
            AddrSubnet::<_, LinkLocalAddr<Ipv4Addr>>::new(Ipv4Addr::new([1, 2, 3, 4]), 32)
                == Err(AddrSubnetError::InvalidWitness)
        );
    }

    #[test]
    fn test_is_unicast_in_subnet() {
        // Valid unicast in subnet
        let subnet =
            Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).expect("1.2.0.0/16 is a valid subnet");
        assert!(Ipv4Addr::new([1, 2, 3, 4]).is_unicast_in_subnet(&subnet));
        assert!(!Ipv4Addr::new([2, 2, 3, 4]).is_unicast_in_subnet(&subnet));

        let subnet =
            Subnet::new(Ipv6Addr::from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 64)
                .expect("1::/64 is a valid subnet");
        assert!(Ipv6Addr::from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
            .is_unicast_in_subnet(&subnet));
        assert!(!Ipv6Addr::from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
            .is_unicast_in_subnet(&subnet));

        // Unspecified address
        assert!(!Ipv4::UNSPECIFIED_ADDRESS
            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 16).unwrap()));
        assert!(!Ipv6::UNSPECIFIED_ADDRESS
            .is_unicast_in_subnet(&Subnet::new(Ipv6::UNSPECIFIED_ADDRESS, 64).unwrap()));
        // The "31- or 32-bit prefix" exception doesn't apply to the unspecified
        // address (IPv4 only).
        assert!(!Ipv4::UNSPECIFIED_ADDRESS
            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 31).unwrap()));
        assert!(!Ipv4::UNSPECIFIED_ADDRESS
            .is_unicast_in_subnet(&Subnet::new(Ipv4::UNSPECIFIED_ADDRESS, 32).unwrap()));
        // All-zeroes host part (IPv4 only)
        assert!(!Ipv4Addr::new([1, 2, 0, 0])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).unwrap()));
        // Exception: 31- or 32-bit prefix (IPv4 only)
        assert!(Ipv4Addr::new([1, 2, 3, 0])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 3, 0]), 31).unwrap()));
        assert!(Ipv4Addr::new([1, 2, 3, 0])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 3, 0]), 32).unwrap()));
        // Limited broadcast (IPv4 only)
        assert!(!Ipv4::LIMITED_BROADCAST_ADDRESS
            .get()
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([128, 0, 0, 0]), 1).unwrap()));
        // Subnet broadcast (IPv4 only)
        assert!(!Ipv4Addr::new([1, 2, 255, 255])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 0, 0]), 16).unwrap()));
        // Exception: 31- or 32-bit prefix (IPv4 only)
        assert!(Ipv4Addr::new([1, 2, 255, 255])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 255, 254]), 31).unwrap()));
        assert!(Ipv4Addr::new([1, 2, 255, 255])
            .is_unicast_in_subnet(&Subnet::new(Ipv4Addr::new([1, 2, 255, 255]), 32).unwrap()));
        // Multicast
        assert!(!Ipv4Addr::new([224, 0, 0, 1]).is_unicast_in_subnet(&Ipv4::MULTICAST_SUBNET));
        assert!(!Ipv6Addr::from([0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
            .is_unicast_in_subnet(&Ipv6::MULTICAST_SUBNET));
        // Class E (IPv4 only)
        assert!(!Ipv4Addr::new([240, 0, 0, 1]).is_unicast_in_subnet(&Ipv4::CLASS_E_SUBNET));
    }

    macro_rules! add_mask_test {
            ($name:ident, $addr:ident, $from_ip:expr => {
                $($mask:expr => $to_ip:expr),*
            }) => {
                #[test]
                fn $name() {
                    let from = $addr::from($from_ip);
                    $(assert_eq!(from.mask($mask), $addr::from($to_ip), "(`{}`.mask({}))", from, $mask);)*
                }
            };
            ($name:ident, $addr:ident, $from_ip:expr => {
                $($mask:expr => $to_ip:expr),*,
            }) => {
                add_mask_test!($name, $addr, $from_ip => { $($mask => $to_ip),* });
            };
        }

    add_mask_test!(v4_full_mask, Ipv4Addr, [255, 254, 253, 252] => {
        32 => [255, 254, 253, 252],
        28 => [255, 254, 253, 240],
        24 => [255, 254, 253, 0],
        20 => [255, 254, 240, 0],
        16 => [255, 254, 0,   0],
        12 => [255, 240, 0,   0],
        8  => [255, 0,   0,   0],
        4  => [240, 0,   0,   0],
        0  => [0,   0,   0,   0],
    });

    add_mask_test!(v6_full_mask, Ipv6Addr,
        [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0] => {
            128 => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0xF1, 0xF0],
            112 => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF2, 0x00, 0x00],
            96  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0xF5, 0xF4, 0x00, 0x00, 0x00, 0x00],
            80  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0xF7, 0xF6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            64  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            48  => [0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            32  => [0xFF, 0xFE, 0xFD, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            16  => [0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            8   => [0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
            0   => [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
        }
    );

    #[test_case([255, 255, 255, 0] => Ok(24))]
    #[test_case([255, 255, 254, 0] => Ok(23))]
    #[test_case([255, 255, 253, 0] => Err(NotSubnetMaskError))]
    #[test_case([255, 255, 0, 255] => Err(NotSubnetMaskError))]
    #[test_case([255, 255, 255, 255] => Ok(32))]
    #[test_case([0, 0, 0, 0] => Ok(0))]
    #[test_case([0, 0, 0, 255] => Err(NotSubnetMaskError))]
    fn test_ipv4_prefix_len_try_from_subnet_mask(
        subnet_mask: [u8; 4],
    ) -> Result<u8, NotSubnetMaskError> {
        let subnet_mask = Ipv4Addr::from(subnet_mask);
        PrefixLength::<Ipv4>::try_from_subnet_mask(subnet_mask).map(|prefix_len| prefix_len.get())
    }

    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(64))]
    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(63))]
    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0, 0, 0, 0, 0, 0, 0, 0] => Err(NotSubnetMaskError))]
    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0, 0, 0, 0, 0, 0, 0, 1] => Err(NotSubnetMaskError))]
    #[test_case([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] => Ok(0))]
    #[test_case([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] => Ok(128))]
    #[test_case([0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0] => Err(NotSubnetMaskError))]
    fn test_ipv6_prefix_len_try_from_subnet_mask(
        subnet_mask: [u8; 16],
    ) -> Result<u8, NotSubnetMaskError> {
        let subnet_mask = Ipv6Addr::from(subnet_mask);
        PrefixLength::<Ipv6>::try_from_subnet_mask(subnet_mask).map(|prefix_len| prefix_len.get())
    }

    #[test_case(0 => true)]
    #[test_case(1 => true)]
    #[test_case(32 => true)]
    #[test_case(33 => false)]
    #[test_case(128 => false)]
    #[test_case(129 => false)]
    #[test_case(255 => false)]
    fn test_ipv4_prefix_len_new(prefix_len: u8) -> bool {
        PrefixLength::<Ipv4>::new(prefix_len).is_ok()
    }

    #[test_case(0 => true)]
    #[test_case(1 => true)]
    #[test_case(32 => true)]
    #[test_case(33 => true)]
    #[test_case(128 => true)]
    #[test_case(129 => false)]
    #[test_case(255 => false)]
    fn test_ipv6_prefix_len_new(prefix_len: u8) -> bool {
        PrefixLength::<Ipv6>::new(prefix_len).is_ok()
    }

    #[test_case(0 => [0, 0, 0, 0])]
    #[test_case(6 => [252, 0, 0, 0])]
    #[test_case(16 => [255, 255, 0, 0])]
    #[test_case(25 => [255, 255, 255, 128])]
    #[test_case(32 => [255, 255, 255, 255])]
    fn test_ipv4_prefix_len_get_mask(prefix_len: u8) -> [u8; 4] {
        let Ipv4Addr(inner) = PrefixLength::<Ipv4>::new(prefix_len).unwrap().get_mask();
        inner
    }

    #[test_case(0 => [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
    #[test_case(6 => [0xFC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])]
    #[test_case(64 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0])]
    #[test_case(65 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0, 0, 0, 0, 0, 0, 0])]
    #[test_case(128 => [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])]
    fn test_ipv6_prefix_len_get_mask(prefix_len: u8) -> [u8; 16] {
        let Ipv6Addr(inner) = PrefixLength::<Ipv6>::new(prefix_len).unwrap().get_mask();
        inner
    }

    #[test]
    fn test_ipv6_solicited_node() {
        let addr = Ipv6Addr::new([0xfe80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
        let solicited = Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0x01, 0xffb5, 0x5aa0]);
        assert_eq!(addr.to_solicited_node_address().get(), solicited);
    }

    #[test]
    fn test_ipv6_address_types() {
        assert!(!Ipv6Addr::from([0; 16]).is_specified());
        assert!(Ipv6Addr::new([0, 0, 0, 0, 0, 0, 0, 1]).is_loopback());
        let link_local = Ipv6Addr::new([0xfe80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
        assert!(link_local.is_link_local());
        assert!(link_local.is_valid_unicast());
        assert!(link_local.to_solicited_node_address().is_multicast());
        let global_unicast = Ipv6Addr::new([0x80, 0, 0, 0, 0x52e5, 0x49ff, 0xfeb5, 0x5aa0]);
        assert!(global_unicast.is_valid_unicast());
        assert!(global_unicast.to_solicited_node_address().is_multicast());

        let multi = Ipv6Addr::new([0xff02, 0, 0, 0, 0, 0x01, 0xffb5, 0x5aa0]);
        assert!(multi.is_multicast());
        assert!(!multi.is_valid_unicast());
    }

    #[test]
    fn test_const_witness() {
        // Test that all of the addresses that we initialize at compile time
        // using `new_unchecked` constructors are valid for their witness types.
        assert!(Ipv4::LOOPBACK_ADDRESS.0.is_specified());
        assert!(Ipv6::LOOPBACK_ADDRESS.0.is_specified());
        assert!(Ipv4::LIMITED_BROADCAST_ADDRESS.0.is_specified());
        assert!(Ipv4::ALL_ROUTERS_MULTICAST_ADDRESS.0.is_multicast());
        assert!(Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS.0.is_multicast());
        assert!(Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS.0.is_multicast());
    }

    #[test]
    fn test_ipv6_scope() {
        use Ipv6ReservedScope::*;
        use Ipv6Scope::*;
        use Ipv6UnassignedScope::*;

        // Test unicast scopes.
        assert_eq!(Ipv6::SITE_LOCAL_UNICAST_SUBNET.network.scope(), SiteLocal);
        assert_eq!(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network.scope(), LinkLocal);
        assert_eq!(Ipv6::UNSPECIFIED_ADDRESS.scope(), Global);

        // Test multicast scopes.
        let assert_scope = |value, scope| {
            let mut addr = Ipv6::MULTICAST_SUBNET.network;
            // Set the "scop" field manually.
            addr.0[1] |= value;
            assert_eq!(addr.scope(), scope);
        };
        assert_scope(0, Reserved(Scope0));
        assert_scope(1, InterfaceLocal);
        assert_scope(2, LinkLocal);
        assert_scope(3, Reserved(Scope3));
        assert_scope(4, AdminLocal);
        assert_scope(5, SiteLocal);
        assert_scope(6, Unassigned(Scope6));
        assert_scope(7, Unassigned(Scope7));
        assert_scope(8, OrganizationLocal);
        assert_scope(9, Unassigned(Scope9));
        assert_scope(0xA, Unassigned(ScopeA));
        assert_scope(0xB, Unassigned(ScopeB));
        assert_scope(0xC, Unassigned(ScopeC));
        assert_scope(0xD, Unassigned(ScopeD));
        assert_scope(0xE, Global);
        assert_scope(0xF, Reserved(ScopeF));
    }

    #[test]
    fn test_ipv6_multicast_scope_id() {
        const ALL_SCOPES: &[Ipv6Scope] = &[
            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope0),
            Ipv6Scope::InterfaceLocal,
            Ipv6Scope::LinkLocal,
            Ipv6Scope::Reserved(Ipv6ReservedScope::Scope3),
            Ipv6Scope::AdminLocal,
            Ipv6Scope::SiteLocal,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope6),
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope7),
            Ipv6Scope::OrganizationLocal,
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::Scope9),
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeA),
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeB),
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeC),
            Ipv6Scope::Unassigned(Ipv6UnassignedScope::ScopeD),
            Ipv6Scope::Global,
            Ipv6Scope::Reserved(Ipv6ReservedScope::ScopeF),
        ];
        for (i, a) in ALL_SCOPES.iter().enumerate() {
            assert_eq!(a.multicast_scope_id(), i.try_into().unwrap());
        }
    }

    #[test]
    fn test_ipv4_embedded() {
        // Test Ipv4Addr's to_ipv6_compatible and to_ipv6_mapped methods.

        assert_eq!(
            Ipv4Addr::new([1, 2, 3, 4]).to_ipv6_compatible(),
            Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4])
        );
        assert_eq!(
            Ipv4Addr::new([1, 2, 3, 4]).to_ipv6_mapped().get(),
            Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 1, 2, 3, 4]),
        );

        // Test Ipv6Addr's to_ipv4_compatible and to_ipv4_mapped methods.

        let compatible = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4]);
        let mapped = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 1, 2, 3, 4]);
        let not_embedded = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 1, 2, 3, 4]);
        let v4 = Ipv4Addr::new([1, 2, 3, 4]);

        assert_eq!(compatible.to_ipv4_compatible(), Some(v4));
        assert_eq!(compatible.to_ipv4_mapped(), None);

        assert_eq!(mapped.to_ipv4_compatible(), None);
        assert_eq!(mapped.to_ipv4_mapped(), Some(v4));

        assert_eq!(not_embedded.to_ipv4_compatible(), None);
        assert_eq!(not_embedded.to_ipv4_mapped(), None);

        assert_eq!(
            NonMappedAddr::new(compatible),
            Some(unsafe { NonMappedAddr::new_unchecked(compatible) })
        );
        assert_eq!(NonMappedAddr::new(mapped), None);
        assert_eq!(
            NonMappedAddr::new(not_embedded),
            Some(unsafe { NonMappedAddr::new_unchecked(not_embedded) })
        );
        assert_eq!(NonMappedAddr::new(v4), Some(unsafe { NonMappedAddr::new_unchecked(v4) }));
    }

    #[test]
    fn test_common_prefix_len_ipv6() {
        let ip1 = Ipv6Addr::from([0xFF, 0xFF, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
        let ip2 = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
        let ip3 = Ipv6Addr::from([0xFF, 0xFF, 0x80, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
        let ip4 = Ipv6Addr::from([0xFF, 0xFF, 0xC0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
        let compare_with_ip1 = |target, expect| {
            assert_eq!(ip1.common_prefix_len(&target), expect, "{} <=> {}", ip1, target);
        };
        compare_with_ip1(ip1, 128);
        compare_with_ip1(ip2, 0);
        compare_with_ip1(ip3, 24);
        compare_with_ip1(ip4, 17);
    }

    #[test]
    fn test_common_prefix_len_ipv4() {
        let ip1 = Ipv4Addr::new([0xFF, 0xFF, 0x80, 0]);
        let ip2 = Ipv4Addr::new([0, 0, 0, 0]);
        let ip3 = Ipv4Addr::new([0xFF, 0xFF, 0x80, 0xFF]);
        let ip4 = Ipv4Addr::new([0xFF, 0xFF, 0xC0, 0x20]);
        let compare_with_ip1 = |target, expect| {
            assert_eq!(ip1.common_prefix_len(&target), expect, "{} <=> {}", ip1, target);
        };
        compare_with_ip1(ip1, 32);
        compare_with_ip1(ip2, 0);
        compare_with_ip1(ip3, 24);
        compare_with_ip1(ip4, 17);
    }

    #[test]
    fn test_ipv6_display() {
        // Test that `addr` is formatted the same by our `Display` impl as by
        // the standard library's `Display` impl. Optionally test that it
        // matches a particular expected string.
        fn test_one(addr: Ipv6Addr, expect: Option<&str>) {
            let formatted = format!("{}", addr);
            if let Some(expect) = expect {
                assert_eq!(formatted, expect);
            }

            // NOTE: We use `std` here even though we're not inside of the
            // `std_tests` module because we're using `std` to test
            // functionality that is present even when the `std` Cargo feature
            // is not used.
            //
            // Note that we use `std::net::Ipv6Addr::from(addr.segments())`
            // rather than `std::net::Ipv6Addr::from(addr)` because, when the
            // `std` Cargo feature is disabled, the `From<Ipv6Addr> for
            // std::net::Ipv6Addr` impl is not emitted.
            let formatted_std = format!("{}", std::net::Ipv6Addr::from(addr.segments()));
            assert_eq!(formatted, formatted_std);
        }

        test_one(Ipv6::UNSPECIFIED_ADDRESS, Some("::"));
        test_one(*Ipv6::LOOPBACK_ADDRESS, Some("::1"));
        test_one(Ipv6::MULTICAST_SUBNET.network, Some("ff00::"));
        test_one(Ipv6::LINK_LOCAL_UNICAST_SUBNET.network, Some("fe80::"));
        test_one(*Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::1"));
        test_one(*Ipv6::ALL_NODES_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::1"));
        test_one(*Ipv6::ALL_ROUTERS_LINK_LOCAL_MULTICAST_ADDRESS, Some("ff02::2"));
        test_one(Ipv6::SITE_LOCAL_UNICAST_SUBNET.network, Some("fec0::"));
        test_one(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), Some("1::"));
        test_one(Ipv6Addr::new([0, 0, 0, 1, 2, 3, 4, 5]), Some("::1:2:3:4:5"));

        // Treating each pair of bytes as a bit (either 0x0000 or 0x0001), cycle
        // through every possible IPv6 address. Since the formatting algorithm
        // is only sensitive to zero vs nonzero for any given byte pair, this
        // gives us effectively complete coverage of the input space.
        for byte in 0u8..=255 {
            test_one(
                Ipv6Addr::new([
                    u16::from(byte & 0b1),
                    u16::from((byte & 0b10) >> 1),
                    u16::from((byte & 0b100) >> 2),
                    u16::from((byte & 0b1000) >> 3),
                    u16::from((byte & 0b10000) >> 4),
                    u16::from((byte & 0b100000) >> 5),
                    u16::from((byte & 0b1000000) >> 6),
                    u16::from((byte & 0b10000000) >> 7),
                ]),
                None,
            );
        }
    }

    #[test_case(Ipv4::UNSPECIFIED_ADDRESS, Ipv4AddressClass::A; "first_class_a")]
    #[test_case(Ipv4Addr::new([127, 255, 255, 255]), Ipv4AddressClass::A; "last_class_a")]
    #[test_case(Ipv4Addr::new([128, 0, 0, 0]), Ipv4AddressClass::B; "first_class_b")]
    #[test_case(Ipv4Addr::new([191, 255, 255, 255]), Ipv4AddressClass::B; "last_class_b")]
    #[test_case(Ipv4Addr::new([192, 0, 0, 0]), Ipv4AddressClass::C; "first_class_c")]
    #[test_case(Ipv4Addr::new([223, 255, 255, 255]), Ipv4AddressClass::C; "last_class_c")]
    #[test_case(Ipv4Addr::new([224, 0, 0, 0]), Ipv4AddressClass::D; "first_class_d")]
    #[test_case(Ipv4Addr::new([239, 255, 255, 255]), Ipv4AddressClass::D; "last_class_d")]
    #[test_case(Ipv4Addr::new([240, 0, 0, 0]), Ipv4AddressClass::E; "first_class_e")]
    #[test_case(Ipv4Addr::new([255, 255, 255, 255]), Ipv4AddressClass::E; "last_class_e")]
    fn ipv4addr_class(addr: Ipv4Addr, class: Ipv4AddressClass) {
        assert_eq!(addr.class(), class)
    }

    #[test_case(
        Subnet::new(Ipv4Addr::new([192, 168, 1, 0]), 24).unwrap(),
        Subnet::new(Ipv4Addr::new([192, 168, 2, 0]), 24).unwrap()
    ; "ipv4_same_prefix")]
    #[test_case(
        Subnet::new(Ipv4Addr::new([192, 168, 2, 0]), 24).unwrap(),
        Subnet::new(Ipv4Addr::new([192, 168, 1, 0]), 32).unwrap()
    ; "ipv4_by_prefix")]
    #[test_case(
        Subnet::new(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap(),
        Subnet::new(Ipv6Addr::new([2, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap()
    ; "ipv6_same_prefix")]
    #[test_case(
        Subnet::new(Ipv6Addr::new([2, 0, 0, 0, 0, 0, 0, 0]), 64).unwrap(),
        Subnet::new(Ipv6Addr::new([1, 0, 0, 0, 0, 0, 0, 0]), 128).unwrap()
    ; "ipv6_by_prefix")]
    fn subnet_ord<A: core::cmp::Ord>(a: Subnet<A>, b: Subnet<A>) {
        assert!(a < b);
    }

    #[cfg(feature = "std")]
    mod std_tests {
        use super::*;

        #[test]
        fn test_conversions() {
            let v4 = Ipv4Addr::new([127, 0, 0, 1]);
            let v6 = Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]);
            let std_v4 = net::Ipv4Addr::new(127, 0, 0, 1);
            let std_v6 = net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);

            let converted: IpAddr = net::IpAddr::V4(std_v4).into();
            assert_eq!(converted, IpAddr::V4(v4));
            let converted: IpAddr = net::IpAddr::V6(std_v6).into();
            assert_eq!(converted, IpAddr::V6(v6));

            let converted: net::IpAddr = IpAddr::V4(v4).into();
            assert_eq!(converted, net::IpAddr::V4(std_v4));
            let converted: net::IpAddr = IpAddr::V6(v6).into();
            assert_eq!(converted, net::IpAddr::V6(std_v6));

            let converted: Ipv4Addr = std_v4.into();
            assert_eq!(converted, v4);
            let converted: Ipv6Addr = std_v6.into();
            assert_eq!(converted, v6);

            let converted: net::Ipv4Addr = v4.into();
            assert_eq!(converted, std_v4);
            let converted: net::Ipv6Addr = v6.into();
            assert_eq!(converted, std_v6);
        }
    }
}

/// Tests of the [`GenericOverIp`] derive macro.
#[cfg(test)]
mod macro_test {
    use super::*;

    /// No-op function that will only compile if `T::Type<I> = Other`.
    fn assert_ip_generic_is<T, I, Other>()
    where
        I: Ip,
        T: GenericOverIp<I, Type = Other>,
    {
        // Do nothing; this function just serves to assert that the argument
        // does in fact implement GenericOverIp.
    }

    macro_rules! assert_ip_generic {
        ($name:ident, Ip $(,$($param:ident),*)?) => {
            assert_ip_generic_is::<$name<Ipv4 $(, $($param,)*)?>, Ipv4, $name<Ipv4 $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv4 $(, $($param,)*)?>, Ipv6, $name<Ipv6 $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv6 $(, $($param,)*)?>, Ipv4, $name<Ipv4 $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv6 $(, $($param,)*)?>, Ipv6, $name<Ipv6 $(, $($param,)*)?>>();
        };
        ($name:ident, IpAddress $(,$($param:ident),*)?) => {
            assert_ip_generic_is::<$name<Ipv4Addr $(, $($param,)*)?>, Ipv4, $name<Ipv4Addr $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv4Addr $(, $($param,)*)?>, Ipv6, $name<Ipv6Addr $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv6Addr $(, $($param,)*)?>, Ipv4, $name<Ipv4Addr $(, $($param,)*)?>>();
            assert_ip_generic_is::<$name<Ipv6Addr $(, $($param,)*)?>, Ipv6, $name<Ipv6Addr $(, $($param,)*)?>>();
        };
        ($name:ident $(,$($param:ident),*)?) => {
            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv4, $name<$($($param,)*)?>>();
            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv6, $name<$($($param,)*)?>>();
            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv4, $name<$($($param,)*)?>>();
            assert_ip_generic_is::<$name<$($($param,)*)?>, Ipv6, $name<$($($param,)*)?>>();
        };
    }

    #[test]
    fn struct_with_ip_version_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<I: Ip> {
            addr: I::Addr,
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn struct_with_unbounded_ip_version_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<I> {
            addr: core::marker::PhantomData<I>,
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn struct_with_ip_address_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        struct Generic<A: IpAddress> {
            addr: A,
        }

        assert_ip_generic!(Generic, IpAddress);
    }

    #[test]
    fn struct_with_unbounded_ip_address_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        struct Generic<A> {
            addr: A,
        }

        assert_ip_generic!(Generic, IpAddress);
    }

    #[test]
    fn struct_with_generic_over_ip_parameter() {
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct InnerGeneric<I: Ip> {
            addr: I::Addr,
        }

        #[derive(GenericOverIp)]
        #[generic_over_ip(T, GenericOverIp)]
        struct Generic<T> {
            foo: T,
        }

        fn do_something<I: Ip>(g: Generic<InnerGeneric<I>>) {
            I::map_ip(
                g,
                |g| {
                    let _: Ipv4Addr = g.foo.addr;
                },
                |g| {
                    let _: Ipv6Addr = g.foo.addr;
                },
            )
        }

        do_something::<Ipv4>(Generic { foo: InnerGeneric { addr: Ipv4::UNSPECIFIED_ADDRESS } });

        do_something::<Ipv6>(Generic { foo: InnerGeneric { addr: Ipv6::UNSPECIFIED_ADDRESS } });
    }

    #[test]
    fn enum_with_ip_version_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        enum Generic<I: Ip> {
            A(I::Addr),
            B(I::Addr),
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn enum_with_unbounded_ip_version_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        enum Generic<I> {
            A(core::marker::PhantomData<I>),
            B(core::marker::PhantomData<I>),
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn enum_with_ip_address_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        enum Generic<A: IpAddress> {
            A(A),
            B(A),
        }

        assert_ip_generic!(Generic, IpAddress);
    }

    #[test]
    fn enum_with_unbounded_ip_address_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        enum Generic<A> {
            A(A),
            B(A),
        }

        assert_ip_generic!(Generic, IpAddress);
    }

    #[test]
    fn struct_with_ip_version_and_other_parameters() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct AddrAndDevice<I: Ip, D> {
            addr: I::Addr,
            device: D,
        }
        struct Device;

        assert_ip_generic!(AddrAndDevice, Ip, Device);
    }

    #[test]
    fn enum_with_ip_version_and_other_parameters() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        enum AddrOrDevice<I: Ip, D> {
            Addr(I::Addr),
            Device(D),
        }
        struct Device;

        assert_ip_generic!(AddrOrDevice, Ip, Device);
    }

    #[test]
    fn struct_with_ip_address_and_other_parameters() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        struct AddrAndDevice<A: IpAddress, D> {
            addr: A,
            device: D,
        }
        struct Device;

        assert_ip_generic!(AddrAndDevice, IpAddress, Device);
    }

    #[test]
    fn struct_with_unbounded_ip_address_and_other_parameters() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        struct AddrAndDevice<A, D> {
            addr: A,
            device: D,
        }
        struct Device;

        assert_ip_generic!(AddrAndDevice, IpAddress, Device);
    }

    #[test]
    fn enum_with_ip_address_and_other_parameters() {
        #[allow(dead_code)]
        #[derive(GenericOverIp, Debug, PartialEq)]
        #[generic_over_ip(A, IpAddress)]
        enum AddrOrDevice<A: IpAddress, D> {
            Addr(A),
            Device(D),
        }
        struct Device;

        assert_ip_generic!(AddrOrDevice, IpAddress, Device);
    }

    #[test]
    fn struct_invariant_over_ip() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip()]
        struct Invariant(usize);

        assert_ip_generic!(Invariant);
    }

    #[test]
    fn enum_invariant_over_ip() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip()]
        enum Invariant {
            Usize(usize),
        }

        assert_ip_generic!(Invariant);
    }

    #[test]
    fn struct_invariant_over_ip_with_other_params() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip()]
        struct Invariant<B, C, D>(B, C, D);

        assert_ip_generic!(Invariant, usize, bool, char);
    }

    #[test]
    fn enum_invariant_over_ip_with_other_params() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip()]
        enum Invariant<A, B, C> {
            A(A),
            B(B),
            C(C),
        }

        assert_ip_generic!(Invariant, usize, bool, char);
    }

    #[test]
    fn struct_with_ip_version_extension_parameter() {
        trait FakeIpExt: Ip {
            type Associated;
        }
        impl FakeIpExt for Ipv4 {
            type Associated = u8;
        }
        impl FakeIpExt for Ipv6 {
            type Associated = u16;
        }

        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<I: FakeIpExt> {
            field: I::Associated,
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn struct_with_ip_version_extension_parameter_but_no_ip_bound() {
        trait FakeIpExt: Ip {
            type Associated;
        }
        impl FakeIpExt for Ipv4 {
            type Associated = u8;
        }
        impl FakeIpExt for Ipv6 {
            type Associated = u16;
        }

        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<I: FakeIpExt> {
            field: I::Associated,
        }

        assert_ip_generic!(Generic, Ip);
    }

    #[test]
    fn struct_with_ip_address_extension_parameter() {
        trait FakeIpAddressExt: IpAddress {
            type Associated;
        }
        impl FakeIpAddressExt for Ipv4Addr {
            type Associated = u8;
        }
        impl FakeIpAddressExt for Ipv6Addr {
            type Associated = u16;
        }

        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(A, IpAddress)]
        struct Generic<A: IpAddress + FakeIpAddressExt> {
            field: A::Associated,
        }

        assert_ip_generic!(Generic, IpAddress);
    }

    #[test]
    fn type_with_lifetime_and_ip_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<'a, I: Ip> {
            field: &'a I::Addr,
        }

        assert_ip_generic_is::<Generic<'static, Ipv4>, Ipv4, Generic<'static, Ipv4>>();
        assert_ip_generic_is::<Generic<'static, Ipv4>, Ipv6, Generic<'static, Ipv6>>();
        assert_ip_generic_is::<Generic<'static, Ipv6>, Ipv4, Generic<'static, Ipv4>>();
        assert_ip_generic_is::<Generic<'static, Ipv6>, Ipv6, Generic<'static, Ipv6>>();
    }

    #[test]
    fn type_with_lifetime_and_no_ip_parameter() {
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip()]
        struct Generic<'a> {
            field: &'a (),
        }

        assert_ip_generic_is::<Generic<'static>, Ipv4, Generic<'static>>();
        assert_ip_generic_is::<Generic<'static>, Ipv6, Generic<'static>>();
    }

    #[test]
    fn type_with_params_list_with_trailing_comma() {
        trait IpExtensionTraitWithVeryLongName {}
        trait OtherIpExtensionTraitWithVeryLongName {}
        trait LongNameToForceFormatterToBreakLineAndAddTrailingComma {}
        // Regression test for https://fxbug.dev/42080215
        #[allow(dead_code)]
        #[derive(GenericOverIp)]
        #[generic_over_ip(I, Ip)]
        struct Generic<
            I: Ip
                + IpExtensionTraitWithVeryLongName
                + OtherIpExtensionTraitWithVeryLongName
                + LongNameToForceFormatterToBreakLineAndAddTrailingComma,
        > {
            field: I::Addr,
        }
    }
}
