1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#[macro_use]
extern crate log;
pub mod io;
pub mod mail;
pub mod smtp;
#[cfg(feature = "server")]
pub mod server;
pub mod common {
pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
pub type Result<T> = std::result::Result<T, Error>;
pub mod io {
pub use futures_io::{
AsyncBufRead as BufRead, AsyncRead as Read, AsyncSeek as Seek, AsyncWrite as Write,
};
pub use std::io::{Error, ErrorKind, Result};
}
pub use futures_core::ready;
use std::any::TypeId;
pub use std::future::*;
pub type S3Fut<T> = Pin<Box<dyn Future<Output = T> + Sync + Send + 'static>>;
pub type S2Fut<'a, T> = Pin<Box<dyn Future<Output = T> + Sync + Send + 'a>>;
pub type S1Fut<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
pub use std::fmt;
pub use std::pin::Pin;
use std::sync::atomic::AtomicU32;
use std::sync::atomic::Ordering;
pub use std::sync::Arc;
pub use std::task::{Context, Poll};
#[derive(Debug, Copy, Clone)]
pub struct Dummy;
pub async fn poll_fn<F, T>(f: F) -> T
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
let fut = PollFn { f };
fut.await
}
struct PollFn<F> {
f: F,
}
impl<F> Unpin for PollFn<F> {}
impl<T, F> Future for PollFn<F>
where
F: FnMut(&mut Context<'_>) -> Poll<T>,
{
type Output = T;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> {
(&mut self.f)(cx)
}
}
#[deprecated(
since = "0.13.1",
note = "Use Identify::now() instead. This shall be removed in 0.14.0"
)]
pub fn time_based_id() -> String {
Identify::now().to_string()
}
pub struct Identify;
impl Identify {
pub fn instance() -> u32 {
static INSTANCE: AtomicU32 = AtomicU32::new(0);
let mut value = INSTANCE.load(Ordering::Relaxed);
if value == 0 {
value = Self::now();
match INSTANCE.compare_exchange(0, value, Ordering::Relaxed, Ordering::Relaxed) {
Ok(_) => value,
Err(value) => value,
}
} else {
value
}
}
pub fn now() -> u32 {
Self::hash(
format!(
"{}.{}.{:?}.{:?}",
env!("CARGO_PKG_VERSION"),
std::process::id(),
std::time::Instant::now(),
TypeId::of::<crate::smtp::SmtpSession>()
)
.as_str(),
)
}
const fn hash(s: &str) -> u32 {
let s = s.as_bytes();
let mut hash = 3581u32;
let mut i = 0usize;
while i < s.len() {
hash = hash.wrapping_mul(33).wrapping_add(s[i] as u32);
i += 1;
}
hash
}
}
}
#[test]
fn identify_instance_is_not_zero() {
assert_ne!(common::Identify::instance(), 0)
}
#[test]
fn identify_instance_stays_constant() {
assert_eq!(common::Identify::instance(), common::Identify::instance())
}
#[test]
fn identify_now_is_not_zero() {
assert_ne!(common::Identify::now(), 0)
}
#[test]
fn identify_now_is_unique() {
assert_ne!(common::Identify::now(), common::Identify::now())
}