ip/traits/
addr.rs

1use core::fmt::{Debug, Display};
2use core::hash::Hash;
3use core::str::FromStr;
4
5use crate::{concrete, error::Error};
6
7/// Address-family independent interface for IP addresses
8///
9/// Methods on `Address` types that are well defined for all address-families
10/// are implemented via this trait.
11///
12/// In general, methods on this trait have signatures and semantics compatible
13/// with methods of the same names on the [`std::net`] address types. Where
14/// there is deviation, this is noted in the method documentation.
15///
16/// See also [`concrete::Address<A>`][crate::concrete::Address] and
17/// [`any::Address`][crate::any::Address] for address-family specific items.
18pub trait Address:
19    Clone + Copy + Debug + Display + FromStr<Err = Error> + Hash + PartialEq + Eq + PartialOrd
20{
21    /// Returns the address-family associated with this IP address.
22    ///
23    /// # Examples
24    ///
25    /// ```
26    /// use ip::{traits::Address as _, Address, Any};
27    ///
28    /// let addr: Address<Any> = "192.0.2.1".parse()?;
29    ///
30    /// assert_eq!(addr.afi().to_string(), "ipv4");
31    /// # Ok::<(), ip::Error>(())
32    /// ```
33    fn afi(&self) -> concrete::Afi;
34
35    /// Returns [`true`] if this is an IPv4 broadcast address
36    /// (`255.255.255.255`). Returns [`false`] for all IPv6 addresses.
37    ///
38    /// An IPv4 broadcast address has all octets set to `255` as defined in
39    /// [RFC 919].
40    ///
41    /// [RFC 919]: https://tools.ietf.org/html/rfc919
42    ///
43    /// # [`std::net`] Compatibility
44    ///
45    /// This method is defined on [`Ipv4Addr`][std::net::Ipv4Addr] but not on
46    /// [`Ipv6Addr`][std::net::Ipv6Addr] or [`IpAddr`][std::net::IpAddr].
47    ///
48    /// This implementation provides the method for addresses of all families,
49    /// but always returns [`false`] for IPv6 addresses.
50    ///
51    /// # Examples
52    ///
53    /// ```
54    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
55    ///
56    /// let v4_broadcast = "255.255.255.255".parse::<Address<Ipv4>>()?;
57    /// let v4_unicast = "203.0.113.1".parse::<Address<Ipv4>>()?;
58    /// let v6_all_ones = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".parse::<Address<Ipv6>>()?;
59    ///
60    /// assert_eq!(v4_broadcast.is_broadcast(), true);
61    /// assert_eq!(v4_unicast.is_broadcast(), false);
62    /// assert_eq!(v6_all_ones.is_broadcast(), false);
63    /// assert_eq!(Address::<Any>::Ipv4(v4_broadcast).is_broadcast(), true);
64    /// # Ok::<(), ip::Error>(())
65    /// ```
66    fn is_broadcast(&self) -> bool;
67
68    /// Returns [`true`] if the address is link-local.
69    ///
70    /// Link-local addresses are those within the prefixes `169.254.0.0/16` for
71    /// IPv4 and `fe80::/10` for IPv6.
72    ///
73    /// See also [`Address::<Ipv6>::unicast_link_local`][crate::concrete::Address::is_unicast_link_local].
74    ///
75    /// See [RFC 3927] and [RFC 4291].
76    ///
77    /// [RFC 3927]: https://tools.ietf.org/html/rfc3927
78    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
79    ///
80    /// # [`std::net`] Compatibility
81    ///
82    /// This method is defined on [`Ipv4Addr`][std::net::Ipv4Addr] but not on
83    /// [`Ipv6Addr`][std::net::Ipv6Addr] or [`IpAddr`][std::net::IpAddr].
84    ///
85    /// This implementation provides the method for addresses of all families.
86    ///
87    /// # Examples
88    ///
89    /// ```
90    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
91    ///
92    /// let v4_link_local = "169.254.254.1".parse::<Address<Ipv4>>()?;
93    /// let v6_link_local = "fe80::1".parse::<Address<Ipv6>>()?;
94    /// let v4_unicast = "203.0.113.1".parse::<Address<Ipv4>>()?;
95    ///
96    /// assert_eq!(v4_link_local.is_link_local(), true);
97    /// assert_eq!(v6_link_local.is_link_local(), true);
98    /// assert_eq!(v4_unicast.is_link_local(), false);
99    /// assert_eq!(Address::<Ipv6>::LOCALHOST.is_link_local(), false);
100    /// # Ok::<(), ip::Error>(())
101    /// ```
102    fn is_link_local(&self) -> bool;
103
104    /// Returns [`true`] if this is a private IPv4 address. Returns [`false`]
105    /// for all IPv6 addresses.
106    ///
107    /// The private address ranges are defined in [RFC 1918] and include:
108    ///
109    ///  - `10.0.0.0/8`
110    ///  - `172.16.0.0/12`
111    ///  - `192.168.0.0/16`
112    ///
113    /// [RFC 1918]: https://tools.ietf.org/html/rfc1918
114    ///
115    /// # [`std::net`] Compatibility
116    ///
117    /// This method is defined on [`Ipv4Addr`][std::net::Ipv4Addr] but not on
118    /// [`Ipv6Addr`][std::net::Ipv6Addr] or [`IpAddr`][std::net::IpAddr].
119    ///
120    /// This implementation provides the method for addresses of all families,
121    /// but always returns [`false`] for IPv6 addresses.
122    ///
123    /// # Examples
124    ///
125    /// ```
126    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
127    ///
128    /// let v4_private = "172.18.0.1".parse::<Address<Ipv4>>()?;
129    /// let v4_unicast = "203.0.113.1".parse::<Address<Ipv4>>()?;
130    ///
131    /// assert_eq!(v4_private.is_private(), true);
132    /// assert_eq!(v4_unicast.is_private(), false);
133    /// assert_eq!(Address::<Ipv6>::LOCALHOST.is_private(), false);
134    /// # Ok::<(), ip::Error>(())
135    /// ```
136    fn is_private(&self) -> bool;
137
138    /// Returns [`true`] if this address is an IPv4 address reserved by IANA
139    /// for future use. [RFC 1112] defines the block of reserved addresses
140    /// as `240.0.0.0/4`. This range normally includes the broadcast address
141    /// `255.255.255.255`, but this implementation explicitly excludes it,
142    /// since it is obviously not reserved for future use.
143    ///
144    /// [RFC 1112]: https://tools.ietf.org/html/rfc1112
145    ///
146    /// # [`std::net`] Compatibility
147    ///
148    /// This method is defined on [`Ipv4Addr`][std::net::Ipv4Addr] but not on
149    /// [`Ipv6Addr`][std::net::Ipv6Addr] or [`IpAddr`][std::net::IpAddr].
150    ///
151    /// This implementation provides the method for addresses of all families,
152    /// but always returns [`false`] for IPv6 addresses.
153    ///
154    /// # Warning
155    ///
156    /// As IANA assigns new addresses, this method will be updated. This may
157    /// result in non-reserved addresses being treated as reserved in code that
158    /// relies on an outdated version of this method.
159    ///
160    /// # Examples
161    ///
162    /// ```
163    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
164    ///
165    /// let v4_reserved = "240.0.0.1".parse::<Address<Ipv4>>()?;
166    /// let v4_unicast = "203.0.113.1".parse::<Address<Ipv4>>()?;
167    ///
168    /// assert_eq!(v4_reserved.is_reserved(), true);
169    /// assert_eq!(v4_unicast.is_reserved(), false);
170    /// assert_eq!(Address::<Ipv4>::BROADCAST.is_reserved(), false);
171    /// # Ok::<(), ip::Error>(())
172    /// ```
173    // TODO: unstable
174    fn is_reserved(&self) -> bool;
175
176    /// Returns [`true`] if this address is part of the IPv4 Shared Address
177    /// Space defined in [RFC 6598] (`100.64.0.0/10`).
178    ///
179    /// [RFC 6598]: https://tools.ietf.org/html/rfc6598
180    ///
181    /// # [`std::net`] Compatibility
182    ///
183    /// This method is defined on [`Ipv4Addr`][std::net::Ipv4Addr] but not on
184    /// [`Ipv6Addr`][std::net::Ipv6Addr] or [`IpAddr`][std::net::IpAddr].
185    ///
186    /// This implementation provides the method for addresses of all families,
187    /// but always returns [`false`] for IPv6 addresses.
188    ///
189    /// # Examples
190    ///
191    /// ```
192    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
193    ///
194    /// let v4_shared = "100.72.1.1".parse::<Address<Ipv4>>()?;
195    /// let v4_unicast = "192.0.2.1".parse::<Address<Ipv4>>()?;
196    /// let v6_ula = "fc00::1".parse::<Address<Any>>()?;
197    ///
198    /// assert_eq!(v4_shared.is_shared(), true);
199    /// assert_eq!(v4_unicast.is_shared(), false);
200    /// assert_eq!(v6_ula.is_shared(), false);
201    /// # Ok::<(), ip::Error>(())
202    /// ```
203    // TODO: unstable
204    fn is_shared(&self) -> bool;
205
206    /// Returns [`true`] if this address is part of the IPv4 "This network"
207    /// prefix defined in [RFC 791] (`0.0.0.0/8`).
208    ///
209    /// [RFC 791]: https://tools.ietf.org/html/rfc791
210    ///
211    /// # Examples
212    ///
213    /// ```
214    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
215    ///
216    /// let v4_thisnet = "0.255.255.255".parse::<Address<Ipv4>>()?;
217    ///
218    /// assert_eq!(v4_thisnet.is_thisnet(), true);
219    /// assert_eq!(Address::<Ipv6>::UNSPECIFIED.is_thisnet(), false);
220    /// # Ok::<(), ip::Error>(())
221    /// ```
222    fn is_thisnet(&self) -> bool;
223
224    /// Returns [`true`] if this is an address reserved for network device
225    /// benchmarking:
226    ///
227    /// - IPv4: `198.18.0.0/15` ([RFC 2544])
228    /// - IPv6: `2001:2::/48` ([RFC 5180])
229    ///
230    /// # Errata
231    ///
232    /// The IPv4 benchmarking range is mistakenly defined in [RFC 2544] as
233    /// `192.18.0.0` through `198.19.255.255`, corrected in [errata 423].
234    ///
235    /// The IPv6 benchmarking range is mistakenly defined in [RFC 5180] as
236    /// `2001:200::/48`, corrected in [errata 1752].
237    ///
238    /// [RFC 2544]: https://tools.ietf.org/html/rfc2544
239    /// [RFC 5180]: https://tools.ietf.org/html/rfc5180
240    /// [errata 423]: https://www.rfc-editor.org/errata/eid423
241    /// [errata 1752]: https://www.rfc-editor.org/errata/eid1752
242    ///
243    /// # Examples
244    ///
245    /// ```
246    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
247    ///
248    /// let v4_benchmarking = "198.19.0.1".parse::<Address<Ipv4>>()?;
249    /// let v6_benchmarking = "2001:2::1".parse::<Address<Ipv6>>()?;
250    ///
251    /// assert_eq!(v4_benchmarking.is_benchmarking(), true);
252    /// assert_eq!(v6_benchmarking.is_benchmarking(), true);
253    /// # Ok::<(), ip::Error>(())
254    /// ```
255    // TODO: unstable
256    fn is_benchmarking(&self) -> bool;
257
258    /// Returns [`true`] if this is an address reserved for documentation:
259    ///
260    /// - IPv4 (defined in [RFC 5737]):
261    ///     - `192.0.2.0/24` (`TEST-NET-1`)
262    ///     - `198.51.100.0/24` (`TEST-NET-2`)
263    ///     - `203.0.113.0/24` (`TEST-NET-3`)
264    /// - IPv6: `2001:db8::/32` (defined in [RFC 3849])
265    ///
266    /// [RFC 3849]: https://tools.ietf.org/html/rfc3849
267    /// [RFC 5737]: https://tools.ietf.org/html/rfc5737
268    ///
269    /// # Examples
270    ///
271    /// ```
272    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
273    ///
274    /// let v4_test_net_2 = "198.51.100.1".parse::<Address<Ipv4>>()?;
275    /// let v6_documentation = "2001:db8::1".parse::<Address<Ipv6>>()?;
276    ///
277    /// assert_eq!(v4_test_net_2.is_documentation(), true);
278    /// assert_eq!(v6_documentation.is_documentation(), true);
279    /// # Ok::<(), ip::Error>(())
280    /// ```
281    // TODO: unstable
282    fn is_documentation(&self) -> bool;
283
284    /// Returns [`true`] if this address appears to be globally reachable.
285    ///
286    /// # IPv4
287    ///
288    /// An IPv4 address is considered globally reachable unless it is contained
289    /// in a prefix appearing in the [IANA IPv4 Special-Purpose Address
290    /// Registry], with the value "False" in the column "Globally Reachable"
291    ///
292    /// # IPv6
293    ///
294    /// An IPv6 address is considered globally reachable unless it is contained
295    /// in a prefix appearing in the [IANA IPv6 Special-Purpose Address
296    /// Registry], with the value "False" in the column "Globally Reachable"
297    ///
298    /// [IANA IPv4 Special-Purpose Address Registry]:
299    /// https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
300    /// [IANA IPv6 Special-Purpose Address Registry]:
301    /// https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
302    ///
303    /// # [`std::net`] Compatibility
304    ///
305    /// The implementation of this method on the items of [`std::net`] do not
306    /// consider the scope of IPv4 multicast addresses, all of which return
307    /// [`true`].
308    ///
309    /// This implementation correctly returns [`true`] or [`false`] for IPv4
310    /// multicast addresses, according to their designated scope.
311    // TODO: Add RFC references
312    ///
313    /// # Examples
314    ///
315    /// ```
316    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
317    ///
318    /// // private addresses are not global
319    /// assert_eq!("10.254.0.0".parse::<Address<Ipv4>>()?.is_global(), false);
320    /// assert_eq!("192.168.10.65".parse::<Address<Ipv4>>()?.is_global(), false);
321    /// assert_eq!("172.16.10.65".parse::<Address<Ipv4>>()?.is_global(), false);
322    ///
323    /// // ULA addresses are not global
324    /// assert_eq!("fc00::1".parse::<Address<Ipv6>>()?.is_global(), false);
325    ///
326    /// // the 0.0.0.0/8 block is not global
327    /// assert_eq!("0.1.2.3".parse::<Address<Ipv4>>()?.is_global(), false);
328    /// // in particular, the unspecified addresses are not global
329    /// assert_eq!(Address::<Ipv4>::UNSPECIFIED.is_global(), false);
330    /// assert_eq!(Address::<Ipv6>::UNSPECIFIED.is_global(), false);
331    ///
332    /// // the loopback address is not global
333    /// assert_eq!(Address::<Ipv4>::LOCALHOST.is_global(), false);
334    /// assert_eq!(Address::<Ipv6>::LOCALHOST.is_global(), false);
335    ///
336    /// // link local addresses are not global
337    /// assert_eq!("169.254.45.1".parse::<Address<Ipv4>>()?.is_global(), false);
338    /// assert_eq!("fe80::1".parse::<Address<Ipv6>>()?.is_global(), false);
339    ///
340    /// // the broadcast address is not global
341    /// assert_eq!(Address::<Ipv4>::BROADCAST.is_global(), false);
342    ///
343    /// // the address space designated for documentation is not global
344    /// assert_eq!("192.0.2.255".parse::<Address<Ipv4>>()?.is_global(), false);
345    /// assert_eq!("198.51.100.65".parse::<Address<Ipv4>>()?.is_global(), false);
346    /// assert_eq!("203.0.113.6".parse::<Address<Ipv4>>()?.is_global(), false);
347    /// assert_eq!("2001:db8::1".parse::<Address<Ipv6>>()?.is_global(), false);
348    ///
349    /// // shared addresses are not global
350    /// assert_eq!("100.100.0.0".parse::<Address<Ipv4>>()?.is_global(), false);
351    ///
352    /// // addresses reserved for protocol assignment are not global in general
353    /// assert_eq!("192.0.0.0".parse::<Address<Ipv4>>()?.is_global(), false);
354    /// assert_eq!("192.0.0.255".parse::<Address<Ipv4>>()?.is_global(), false);
355    /// assert_eq!("2001:100::1".parse::<Address<Ipv6>>()?.is_global(), false);
356    /// // but exceptions exist
357    /// assert_eq!("192.0.0.9".parse::<Address<Ipv4>>()?.is_global(), true);
358    /// assert_eq!("2001:20::1".parse::<Address<Ipv6>>()?.is_global(), true);
359    ///
360    /// // addresses reserved for future use are not global
361    /// assert_eq!("250.10.20.30".parse::<Address<Ipv4>>()?.is_global(), false);
362    ///
363    /// // addresses reserved for network devices benchmarking are not global
364    /// assert_eq!("198.18.0.0".parse::<Address<Ipv4>>()?.is_global(), false);
365    /// assert_eq!("2001:2::1".parse::<Address<Ipv6>>()?.is_global(), false);
366    ///
367    /// // multicast addresses are global if so permitted by their scope
368    /// assert_eq!("224.0.0.1".parse::<Address<Ipv4>>()?.is_global(), false);
369    /// assert_eq!("239.0.0.1".parse::<Address<Ipv4>>()?.is_global(), false);
370    /// assert_eq!("ff08::1".parse::<Address<Ipv6>>()?.is_global(), false);
371    /// assert_eq!("224.0.1.1".parse::<Address<Ipv4>>()?.is_global(), true);
372    /// assert_eq!("ff0e::1".parse::<Address<Ipv6>>()?.is_global(), true);
373    ///
374    /// // All the other addresses are global
375    /// assert_eq!("1.1.1.1".parse::<Address<Ipv4>>()?.is_global(), true);
376    /// assert_eq!(
377    ///     "2606:4700:4700::1111".parse::<Address<Ipv6>>()?.is_global(),
378    ///     true
379    /// );
380    /// # Ok::<(), ip::Error>(())
381    /// ```
382    // TODO: unstable
383    fn is_global(&self) -> bool;
384
385    /// Returns [`true`] if this is a loopback address.
386    ///
387    /// - IPv4: `127.0.0.0/8` (defined in [RFC 1122]):
388    /// - IPv6: `::1` (defined in [RFC 4291])
389    ///
390    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
391    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
392    ///
393    /// # Examples
394    ///
395    /// ```
396    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
397    ///
398    /// let v4_loopback = "127.0.0.53".parse::<Address<Ipv4>>()?;
399    /// let v6_loopback = "::1".parse::<Address<Ipv6>>()?;
400    ///
401    /// assert_eq!(v4_loopback.is_loopback(), true);
402    /// assert_eq!(v6_loopback.is_loopback(), true);
403    /// # Ok::<(), ip::Error>(())
404    /// ```
405    fn is_loopback(&self) -> bool;
406
407    /// Returns [`true`] if this is a multicast address.
408    ///
409    /// - IPv4: `224.0.0.0/8` (defined in [RFC 5771]):
410    /// - IPv6: `ff00::/8` (defined in [RFC 4291])
411    ///
412    /// [RFC 5771]: https://tools.ietf.org/html/rfc5771
413    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
414    ///
415    /// # Examples
416    ///
417    /// ```
418    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
419    ///
420    /// let v4_multicast = "224.254.0.0".parse::<Address<Ipv4>>()?;
421    /// let v4_unicast = "172.16.10.65".parse::<Address<Ipv4>>()?;
422    /// let v6_multicast = "ff01::1".parse::<Address<Ipv6>>()?;
423    ///
424    /// assert_eq!(v4_multicast.is_multicast(), true);
425    /// assert_eq!(v6_multicast.is_multicast(), true);
426    /// assert_eq!(v4_unicast.is_multicast(), false);
427    /// # Ok::<(), ip::Error>(())
428    /// ```
429    fn is_multicast(&self) -> bool;
430
431    /// Returns [`true`] for the special "unspecified" address, also called
432    /// "this host on this network" in IPv4.
433    ///
434    /// - IPv4: `0.0.0.0` (defined in [RFC 1122]):
435    /// - IPv6: `::` (defined in [RFC 4291])
436    ///
437    /// [RFC 1122]: https://tools.ietf.org/html/rfc1122
438    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
439    ///
440    /// # Examples
441    ///
442    /// ```
443    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
444    ///
445    /// let v4_unspecified = "0.0.0.0".parse::<Address<Ipv4>>()?;
446    /// let v6_unspecified = "::".parse::<Address<Ipv6>>()?;
447    ///
448    /// assert_eq!(v4_unspecified.is_unspecified(), true);
449    /// assert_eq!(v6_unspecified.is_unspecified(), true);
450    /// # Ok::<(), ip::Error>(())
451    /// ```
452    fn is_unspecified(&self) -> bool;
453
454    /// Returns [`true`] if this is an IPv6 unique local address (`fc00::/7`
455    /// [RFC 4193]).
456    ///
457    /// # [`std::net`] Compatibility
458    ///
459    /// This method is defined on [`Ipv6Addr`][std::net::Ipv6Addr] but not on
460    /// [`Ipv4Addr`][std::net::Ipv4Addr] or [`IpAddr`][std::net::IpAddr].
461    ///
462    /// Unique local addresses are specific to IPv6. The closest analogue for
463    /// IPv4 is the "private" address space: see
464    /// [`is_private()`][Self::is_private()].
465    ///
466    /// This implementation provides the method for addresses of all families,
467    /// but always returns [`false`] for IPv4 addresses.
468    ///
469    /// [RFC 4193]: https://tools.ietf.org/html/rfc4193
470    ///
471    /// # Examples
472    ///
473    /// ```
474    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
475    ///
476    /// let v6_ula = "fc01::1".parse::<Address<Ipv6>>()?;
477    /// let v6_doc = "2001:db8::1".parse::<Address<Ipv6>>()?;
478    /// let v4_private = "192.168.1.1".parse::<Address<Ipv4>>()?;
479    ///
480    /// assert_eq!(v6_ula.is_unique_local(), true);
481    /// assert_eq!(v6_doc.is_unique_local(), false);
482    /// assert_eq!(v4_private.is_unique_local(), false);
483    /// # Ok::<(), ip::Error>(())
484    /// ```
485    // TODO: unstable
486    fn is_unique_local(&self) -> bool;
487
488    /// Returns [`true`] if this is neither a multicase nor a broadcast
489    /// address. See [`is_multicast()`][Self::is_multicast()] and
490    /// [`is_broadcast()`][Self::is_broadcast()].
491    ///
492    /// # [`std::net`] Compatibility
493    ///
494    /// This method is defined on [`Ipv6Addr`][std::net::Ipv6Addr] but not on
495    /// [`Ipv4Addr`][std::net::Ipv4Addr] or [`IpAddr`][std::net::IpAddr].
496    ///
497    /// This implementation provides the method for addresses of all families.
498    ///
499    /// # Examples
500    ///
501    /// ```
502    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
503    ///
504    /// let v6_unicast = "2001:db8::1".parse::<Address<Ipv6>>()?;
505    /// let v6_multicast = "ffaa::1".parse::<Address<Ipv6>>()?;
506    /// let v4_unicast = "192.168.1.1".parse::<Address<Ipv4>>()?;
507    /// let v4_multicast = "239.0.0.1".parse::<Address<Ipv4>>()?;
508    /// let v4_broadcast = "255.255.255.255".parse::<Address<Ipv4>>()?;
509    ///
510    /// assert_eq!(v6_unicast.is_unicast(), true);
511    /// assert_eq!(v6_multicast.is_unicast(), false);
512    /// assert_eq!(v4_unicast.is_unicast(), true);
513    /// assert_eq!(v4_multicast.is_unicast(), false);
514    /// assert_eq!(v4_broadcast.is_unicast(), false);
515    /// # Ok::<(), ip::Error>(())
516    /// ```
517    // TODO: unstable
518    fn is_unicast(&self) -> bool {
519        !(self.is_multicast() || self.is_broadcast())
520    }
521
522    /// Returns [`true`] if this is a unicast address that is gloablly
523    /// routable. See [`is_unicast()`][Self::is_unicast()] and
524    /// [`is_global()`][Self::is_global()].
525    ///
526    /// # [`std::net`] Compatibility
527    ///
528    /// This method is defined on [`Ipv6Addr`][std::net::Ipv6Addr] but not on
529    /// [`Ipv4Addr`][std::net::Ipv4Addr] or [`IpAddr`][std::net::IpAddr].
530    ///
531    /// This implementation provides the method for addresses of all families.
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// use ip::{traits::Address as _, Address, Any, Ipv4, Ipv6};
537    ///
538    /// let v4_unicast_global = "1.1.1.1".parse::<Address<Ipv4>>()?;
539    /// let v4_unicast_private = "192.168.1.1".parse::<Address<Ipv4>>()?;
540    /// let v4_multicast_global = "225.0.0.1".parse::<Address<Ipv4>>()?;
541    /// let v6_unicast_global = "2606:4700:4700::1111".parse::<Address<Ipv6>>()?;
542    /// let v6_unicast_doc = "2001:db8::1".parse::<Address<Ipv6>>()?;
543    /// let v6_multicast_global = "ff0e::1".parse::<Address<Ipv6>>()?;
544    ///
545    /// assert_eq!(v4_unicast_global.is_unicast_global(), true);
546    /// assert_eq!(v4_unicast_private.is_unicast_global(), false);
547    /// assert_eq!(v4_multicast_global.is_unicast_global(), false);
548    /// assert_eq!(v6_unicast_global.is_unicast_global(), true);
549    /// assert_eq!(v6_unicast_doc.is_unicast_global(), false);
550    /// assert_eq!(v6_multicast_global.is_unicast_global(), false);
551    /// # Ok::<(), ip::Error>(())
552    /// ```
553    // TODO: unstable
554    fn is_unicast_global(&self) -> bool {
555        self.is_unicast() && self.is_global()
556    }
557}