cuprate_types/
address_type.rs

1//! Types of network addresses; used in P2P.
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[cfg(feature = "epee")]
7use cuprate_epee_encoding::{
8    error,
9    macros::bytes::{Buf, BufMut},
10    EpeeValue, Marker,
11};
12
13use strum::{
14    AsRefStr, Display, EnumCount, EnumIs, EnumString, FromRepr, IntoStaticStr, VariantArray,
15};
16
17/// An enumeration of address types.
18///
19/// Used in `cuprate_p2p` and `cuprate_types`
20///
21/// Original definition:
22/// - <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/epee/include/net/enums.h/#L49>
23///
24/// # Serde
25/// This type's `serde` implementation (de)serializes from a [`u8`].
26///
27/// ```rust
28/// use cuprate_types::AddressType as A;
29/// use serde_json::{to_string, from_str};
30///
31/// assert_eq!(from_str::<A>(&"0").unwrap(), A::Invalid);
32/// assert_eq!(from_str::<A>(&"1").unwrap(), A::Ipv4);
33/// assert_eq!(from_str::<A>(&"2").unwrap(), A::Ipv6);
34/// assert_eq!(from_str::<A>(&"3").unwrap(), A::I2p);
35/// assert_eq!(from_str::<A>(&"4").unwrap(), A::Tor);
36///
37/// assert_eq!(to_string(&A::Invalid).unwrap(), "0");
38/// assert_eq!(to_string(&A::Ipv4).unwrap(), "1");
39/// assert_eq!(to_string(&A::Ipv6).unwrap(), "2");
40/// assert_eq!(to_string(&A::I2p).unwrap(), "3");
41/// assert_eq!(to_string(&A::Tor).unwrap(), "4");
42/// ```
43#[derive(
44    Copy,
45    Clone,
46    Default,
47    Debug,
48    PartialEq,
49    Eq,
50    PartialOrd,
51    Ord,
52    Hash,
53    AsRefStr,
54    Display,
55    EnumCount,
56    EnumIs,
57    EnumString,
58    FromRepr,
59    IntoStaticStr,
60    VariantArray,
61)]
62#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
63#[cfg_attr(feature = "serde", serde(untagged, try_from = "u8", into = "u8"))]
64#[repr(u8)]
65pub enum AddressType {
66    #[default]
67    Invalid,
68    Ipv4,
69    Ipv6,
70    I2p,
71    Tor,
72}
73
74impl AddressType {
75    /// Convert [`Self`] to a [`u8`].
76    ///
77    /// ```rust
78    /// use cuprate_types::AddressType as A;
79    ///
80    /// assert_eq!(A::Invalid.to_u8(), 0);
81    /// assert_eq!(A::Ipv4.to_u8(), 1);
82    /// assert_eq!(A::Ipv6.to_u8(), 2);
83    /// assert_eq!(A::I2p.to_u8(), 3);
84    /// assert_eq!(A::Tor.to_u8(), 4);
85    /// ```
86    pub const fn to_u8(self) -> u8 {
87        self as u8
88    }
89
90    /// Convert a [`u8`] to a [`Self`].
91    ///
92    /// # Errors
93    /// This returns [`None`] if `u > 4`.
94    ///
95    /// ```rust
96    /// use cuprate_types::AddressType as A;
97    ///
98    /// assert_eq!(A::from_u8(0), Some(A::Invalid));
99    /// assert_eq!(A::from_u8(1), Some(A::Ipv4));
100    /// assert_eq!(A::from_u8(2), Some(A::Ipv6));
101    /// assert_eq!(A::from_u8(3), Some(A::I2p));
102    /// assert_eq!(A::from_u8(4), Some(A::Tor));
103    /// assert_eq!(A::from_u8(5), None);
104    /// ```
105    pub const fn from_u8(u: u8) -> Option<Self> {
106        Some(match u {
107            0 => Self::Invalid,
108            1 => Self::Ipv4,
109            2 => Self::Ipv6,
110            3 => Self::I2p,
111            4 => Self::Tor,
112            _ => return None,
113        })
114    }
115}
116
117impl From<AddressType> for u8 {
118    fn from(value: AddressType) -> Self {
119        value.to_u8()
120    }
121}
122
123impl TryFrom<u8> for AddressType {
124    type Error = u8;
125    fn try_from(value: u8) -> Result<Self, Self::Error> {
126        match Self::from_u8(value) {
127            Some(s) => Ok(s),
128            None => Err(value),
129        }
130    }
131}
132
133#[cfg(feature = "epee")]
134impl EpeeValue for AddressType {
135    const MARKER: Marker = u8::MARKER;
136
137    fn read<B: Buf>(r: &mut B, marker: &Marker) -> error::Result<Self> {
138        let u = u8::read(r, marker)?;
139        Self::from_u8(u).ok_or(error::Error::Format("u8 was greater than 4"))
140    }
141
142    fn write<B: BufMut>(self, w: &mut B) -> error::Result<()> {
143        let u = self.to_u8();
144        u8::write(u, w)?;
145        Ok(())
146    }
147}