async_pop/response/types/
number.rs

1use std::{
2    borrow::Cow,
3    fmt::{self, Display, Formatter},
4    result, time,
5};
6
7use bytes::Bytes;
8
9use crate::error::{Error, Result};
10
11use super::DataType;
12
13#[derive(Eq, PartialEq, PartialOrd, Ord, Debug, Hash, Clone)]
14/// Represents a Pop3 number data type.
15///
16/// Get its real value by calling `value()` from the [DataType] trait
17pub struct Number {
18    inner: Bytes,
19}
20
21impl TryInto<usize> for Number {
22    type Error = Error;
23
24    fn try_into(self) -> result::Result<usize, Self::Error> {
25        self.value()
26    }
27}
28
29impl From<&[u8]> for Number {
30    fn from(value: &[u8]) -> Self {
31        Self {
32            inner: Bytes::copy_from_slice(value),
33        }
34    }
35}
36
37impl AsRef<[u8]> for Number {
38    fn as_ref(&self) -> &[u8] {
39        &self.inner
40    }
41}
42
43impl From<Bytes> for Number {
44    fn from(value: Bytes) -> Self {
45        Self { inner: value }
46    }
47}
48
49impl Display for Number {
50    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
51        let number = self.as_str_lossy();
52
53        write!(f, "{}", number)
54    }
55}
56
57impl DataType<usize> for Number {
58    fn raw(&self) -> &[u8] {
59        &self.inner
60    }
61
62    fn as_str_lossy(&self) -> Cow<'_, str> {
63        String::from_utf8_lossy(&self.inner)
64    }
65
66    fn as_str(&self) -> Result<&str> {
67        Ok(std::str::from_utf8(&self.inner)?)
68    }
69
70    fn value(&self) -> Result<usize> {
71        let string = self.as_str()?;
72
73        let number: usize = string.parse()?;
74
75        Ok(number)
76    }
77}
78
79#[derive(Eq, PartialEq, PartialOrd, Ord, Debug, Hash, Clone)]
80/// Represents a Pop3 duration data type.
81///
82/// Get its real value by calling `value()` from the [DataType] trait
83pub struct Duration {
84    inner: Number,
85    to_secs_multiplier: u64,
86}
87
88impl Duration {
89    pub fn new<N: Into<Number>>(number: N, to_secs_multiplier: u64) -> Self {
90        Self {
91            inner: number.into(),
92            to_secs_multiplier,
93        }
94    }
95}
96
97impl Display for Duration {
98    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99        let number = self.as_str_lossy();
100
101        write!(f, "{}", number)
102    }
103}
104
105impl TryInto<time::Duration> for Duration {
106    type Error = Error;
107
108    fn try_into(self) -> result::Result<time::Duration, Self::Error> {
109        self.value()
110    }
111}
112
113impl DataType<time::Duration> for Duration {
114    fn raw(&self) -> &[u8] {
115        self.inner.raw()
116    }
117
118    fn as_str_lossy(&self) -> Cow<'_, str> {
119        self.inner.as_str_lossy()
120    }
121
122    fn as_str(&self) -> Result<&str> {
123        self.inner.as_str()
124    }
125
126    fn value(&self) -> Result<time::Duration> {
127        let number = self.inner.value()? as u64;
128
129        let duration = time::Duration::from_secs(number * self.to_secs_multiplier);
130
131        Ok(duration)
132    }
133}