1use core::fmt;
2
3#[cfg(any(test, feature = "arbitrary"))]
4use proptest::{
5 arbitrary::{any, Arbitrary},
6 prop_oneof,
7 strategy::{BoxedStrategy, Strategy},
8};
9
10use super::delegate;
11use crate::{
12 concrete::{self, Ipv4, Ipv6},
13 traits, Error,
14};
15
16#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd)]
29pub enum Length {
30 Ipv4(concrete::PrefixLength<Ipv4>),
32 Ipv6(concrete::PrefixLength<Ipv6>),
34}
35
36impl traits::PrefixLength for Length {
37 fn increment(self) -> Result<Self, Error> {
38 match self {
39 Self::Ipv4(length) => length.increment().map(Self::from),
40 Self::Ipv6(length) => length.increment().map(Self::from),
41 }
42 }
43
44 fn decrement(self) -> Result<Self, Error> {
45 match self {
46 Self::Ipv4(length) => length.decrement().map(Self::from),
47 Self::Ipv6(length) => length.decrement().map(Self::from),
48 }
49 }
50}
51
52impl From<concrete::PrefixLength<Ipv4>> for Length {
53 fn from(length: concrete::PrefixLength<Ipv4>) -> Self {
54 Self::Ipv4(length)
55 }
56}
57
58impl From<concrete::PrefixLength<Ipv6>> for Length {
59 fn from(length: concrete::PrefixLength<Ipv6>) -> Self {
60 Self::Ipv6(length)
61 }
62}
63
64impl AsRef<u8> for Length {
65 delegate! {
66 fn as_ref(&self) -> &u8;
67 }
68}
69
70impl fmt::Display for Length {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 Self::Ipv4(len) => len.fmt(f),
74 Self::Ipv6(len) => len.fmt(f),
75 }
76 }
77}
78
79#[cfg(any(test, feature = "arbitrary"))]
80impl Arbitrary for Length {
81 type Parameters = ();
82 type Strategy = BoxedStrategy<Self>;
83
84 fn arbitrary_with((): Self::Parameters) -> Self::Strategy {
85 prop_oneof![
86 any::<concrete::PrefixLength<Ipv4>>().prop_map(Self::Ipv4),
87 any::<concrete::PrefixLength<Ipv6>>().prop_map(Self::Ipv6),
88 ]
89 .boxed()
90 }
91}