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}