ip/concrete/addr/
convert.rs

1use core::borrow::Borrow;
2
3use super::Address;
4use crate::traits::primitive::{Address as _, IntoIpv6Segments as _};
5use crate::{
6    concrete::{Ipv4, Ipv6},
7    traits::Afi,
8};
9
10// TODO:
11// These should be `impl<A: Afi> From<A::Primitive> for Address<A>`, but that is
12// not allowed by the coherence rules.
13macro_rules! impl_from_primitive {
14    ( $( $af:ident ),* $(,)? ) => {
15        $(
16            impl From<<$af as Afi>::Primitive> for Address<$af> {
17                fn from(primitive: <$af as Afi>::Primitive) -> Self {
18                    Self::new(primitive)
19                }
20            }
21        )*
22    };
23}
24impl_from_primitive! { Ipv4, Ipv6, }
25
26// TODO:
27// Ditto
28macro_rules! impl_try_from_byte_slice {
29    ( $( $af:ident ),* $(,)? ) => {
30        $(
31            impl<'a> TryFrom<&'a [u8]> for Address<$af> {
32                type Error = <<$af as Afi>::Octets as TryFrom<&'a [u8]>>::Error;
33                fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
34                    value.try_into().map(Self::from_octets)
35                }
36            }
37        )*
38    };
39}
40impl_try_from_byte_slice! { Ipv4, Ipv6, }
41
42impl<A, O> From<O> for Address<A>
43where
44    A: Afi<Octets = O>,
45    O: Borrow<[u8]>,
46{
47    fn from(octets: O) -> Self {
48        Self::new(A::Primitive::from_be_bytes(octets))
49    }
50}
51
52impl From<[u16; 8]> for Address<Ipv6> {
53    fn from(segments: [u16; 8]) -> Self {
54        Self::new(<Ipv6 as Afi>::Primitive::from_segments(segments))
55    }
56}
57
58#[cfg(feature = "std")]
59impl From<std::net::Ipv4Addr> for Address<Ipv4> {
60    fn from(addr: std::net::Ipv4Addr) -> Self {
61        Self::new(addr.into())
62    }
63}
64
65#[cfg(feature = "std")]
66impl From<std::net::Ipv6Addr> for Address<Ipv6> {
67    fn from(addr: std::net::Ipv6Addr) -> Self {
68        Self::new(addr.into())
69    }
70}