ip/traits/
interface.rs

1use core::fmt::{Debug, Display};
2use core::hash::Hash;
3use core::str::FromStr;
4
5use super::{Address, Prefix, PrefixLength};
6use crate::error::Error;
7
8/// Address-family independent interface for IP interfaces.
9///
10/// Methods on `Interface` types that are well defined for all address-families
11/// are implemented via this trait.
12///
13/// In general, methods on this trait have signatures and semantics compatible
14/// with methods of the same names on the [`ipnet`] network types. Where
15/// there is deviation, this is noted in the method documentation.
16///
17/// See also [`concrete::Interface<A>`][crate::concrete::Interface] and
18/// [`any::Interface`][crate::any::Interface] for address-family specific items.
19pub trait Interface:
20    Copy + Clone + Debug + Display + FromStr<Err = Error> + Sized + Hash + PartialEq + Eq
21{
22    /// The type of IP address represented by this interface type.
23    type Address: Address;
24
25    /// The type used to represented IP prefixes for this IP interface type.
26    type PrefixLength: PrefixLength;
27
28    /// The type used to represented IP prefix lengths for this IP interface
29    /// type.
30    type Prefix: Prefix;
31
32    /// Returns the network address of the IP subnet containing this interface.
33    ///
34    /// # Examples
35    ///
36    /// ``` rust
37    /// use ip::{traits::Interface as _, Address, Any, Interface, Ipv4, Ipv6};
38    ///
39    /// assert_eq!(
40    ///     "172.16.123.123/16".parse::<Interface<Ipv4>>()?.network(),
41    ///     "172.16.0.0".parse::<Address<Ipv4>>()?,
42    /// );
43    ///
44    /// assert_eq!(
45    ///     "2001:db8:f00::baa/48".parse::<Interface<Ipv6>>()?.network(),
46    ///     "2001:db8:f00::".parse::<Address<Ipv6>>()?,
47    /// );
48    ///
49    /// assert_eq!(
50    ///     "10.255.0.10/16".parse::<Interface<Any>>()?.network(),
51    ///     Address::<Any>::Ipv4("10.255.0.0".parse()?),
52    /// );
53    /// # Ok::<(), ip::Error>(())
54    /// ```
55    fn network(&self) -> Self::Address;
56
57    /// Returns the IP address of this interface.
58    ///
59    /// # Examples
60    ///
61    /// ``` rust
62    /// use ip::{traits::Interface as _, Address, Any, Interface, Ipv4, Ipv6};
63    ///
64    /// assert_eq!(
65    ///     "172.16.123.123/16".parse::<Interface<Ipv4>>()?.addr(),
66    ///     "172.16.123.123".parse::<Address<Ipv4>>()?,
67    /// );
68    ///
69    /// assert_eq!(
70    ///     "2001:db8:f00::baa/48".parse::<Interface<Ipv6>>()?.addr(),
71    ///     "2001:db8:f00::baa".parse::<Address<Ipv6>>()?,
72    /// );
73    ///
74    /// assert_eq!(
75    ///     "10.255.0.10/16".parse::<Interface<Any>>()?.addr(),
76    ///     Address::<Any>::Ipv4("10.255.0.10".parse()?),
77    /// );
78    /// # Ok::<(), ip::Error>(())
79    /// ```
80    fn addr(&self) -> Self::Address;
81
82    /// Returns the IP prefix containing this interface.
83    ///
84    /// # Examples
85    ///
86    /// ``` rust
87    /// use ip::{traits::Interface as _, Any, Interface, Ipv4, Ipv6, Prefix};
88    ///
89    /// assert_eq!(
90    ///     "172.16.123.123/16".parse::<Interface<Ipv4>>()?.trunc(),
91    ///     "172.16.0.0/16".parse::<Prefix<Ipv4>>()?,
92    /// );
93    ///
94    /// assert_eq!(
95    ///     "2001:db8:f00::baa/48".parse::<Interface<Ipv6>>()?.trunc(),
96    ///     "2001:db8:f00::/48".parse::<Prefix<Ipv6>>()?,
97    /// );
98    ///
99    /// assert_eq!(
100    ///     "10.255.0.10/16".parse::<Interface<Any>>()?.trunc(),
101    ///     Prefix::<Any>::Ipv4("10.255.0.0/16".parse()?),
102    /// );
103    /// # Ok::<(), ip::Error>(())
104    /// ```
105    fn trunc(&self) -> Self::Prefix;
106
107    /// Returns the prefix length of this interface.
108    ///
109    /// # Examples
110    ///
111    /// ``` rust
112    /// use ip::{traits::Interface as _, Any, Interface, Ipv4, Ipv6, PrefixLength};
113    ///
114    /// assert_eq!(
115    ///     "172.16.123.123/16".parse::<Interface<Ipv4>>()?.prefix_len(),
116    ///     PrefixLength::<Ipv4>::from_primitive(16)?,
117    /// );
118    ///
119    /// assert_eq!(
120    ///     "2001:db8:f00::baa/48"
121    ///         .parse::<Interface<Ipv6>>()?
122    ///         .prefix_len(),
123    ///     PrefixLength::<Ipv6>::from_primitive(48)?,
124    /// );
125    ///
126    /// assert_eq!(
127    ///     "10.255.0.10/16".parse::<Interface<Any>>()?.prefix_len(),
128    ///     PrefixLength::<Ipv4>::from_primitive(16)?.into(),
129    /// );
130    /// # Ok::<(), ip::Error>(())
131    /// ```
132    fn prefix_len(&self) -> Self::PrefixLength;
133
134    /// Returns the broadcast address of the IP subnet containing this
135    /// interface.
136    ///
137    /// # [`ipnet`] Compatibility
138    ///
139    /// The term "broadcast address" has no meaning when applied to IPv6
140    /// subnets. However, for compatibility with [`ipnet::Ipv6Net`], this
141    /// method will return the last address covered by the prefix in all
142    /// cases.
143    ///
144    /// # Examples
145    ///
146    /// ``` rust
147    /// use ip::{traits::Interface as _, Address, Any, Interface, Ipv4, Ipv6};
148    ///
149    /// assert_eq!(
150    ///     "172.16.123.123/16".parse::<Interface<Ipv4>>()?.broadcast(),
151    ///     "172.16.255.255".parse::<Address<Ipv4>>()?,
152    /// );
153    ///
154    /// assert_eq!(
155    ///     "2001:db8:f00::baa/48"
156    ///         .parse::<Interface<Ipv6>>()?
157    ///         .broadcast(),
158    ///     "2001:db8:f00:ffff:ffff:ffff:ffff:ffff".parse::<Address<Ipv6>>()?,
159    /// );
160    ///
161    /// assert_eq!(
162    ///     "2001:db8:dead:beef::/64"
163    ///         .parse::<Interface<Any>>()?
164    ///         .broadcast(),
165    ///     Address::<Any>::Ipv6("2001:db8:dead:beef:ffff:ffff:ffff:ffff".parse()?),
166    /// );
167    /// # Ok::<(), ip::Error>(())
168    /// ```
169    fn broadcast(&self) -> Self::Address;
170}