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
139
140
141
142
143
144
145
use crate::ctx_mut;
use crate::dirs::Dirs;
use crate::error::Error;
use crate::event::Event;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fs::File;
use std::io::{BufReader, BufWriter};
use std::net::SocketAddr;
use std::path::Path;
pub type R<T> = Result<T, Error>;
pub type Token = u64;
pub type ConnectTerminator = tokio::sync::mpsc::Sender<()>;
pub fn connect_terminator() -> (ConnectTerminator, tokio::sync::mpsc::Receiver<()>) {
tokio::sync::mpsc::channel(1)
}
#[cfg(any(
all(
unix,
not(any(target_os = "android", target_os = "androideabi", target_os = "ios"))
),
windows
))]
#[inline]
pub fn project_dir() -> R<Dirs> {
let dirs = directories::ProjectDirs::from("net", "MaidSafe", "quic-p2p")
.ok_or_else(|| Error::Io(::std::io::ErrorKind::NotFound.into()))?;
Ok(Dirs::Desktop(dirs))
}
#[cfg(not(any(
all(
unix,
not(any(target_os = "android", target_os = "androideabi", target_os = "ios"))
),
windows
)))]
#[inline]
pub fn project_dir() -> R<Dirs> {
Err(Error::Configuration(
"No default project dir on non-desktop platforms. User must provide an override path."
.to_string(),
))
}
#[inline]
pub fn bin_data_format(data: &[u8]) -> String {
let len = data.len();
if len < 8 {
return format!("[ {:?} ]", data);
}
format!(
"[ {:02x} {:02x} {:02x} {:02x}..{:02x} {:02x} {:02x} {:02x} ]",
data[0],
data[1],
data[2],
data[3],
data[len - 4],
data[len - 3],
data[len - 2],
data[len - 1]
)
}
#[inline]
pub fn handle_communication_err(
peer_addr: SocketAddr,
e: &Error,
details: &str,
unsent_user_msg: Option<(bytes::Bytes, Token)>,
) {
debug!(
"ERROR in communication with peer {}: {:?} - {}. Details: {}",
peer_addr, e, e, details
);
ctx_mut(|c| {
let _ = c.connections.remove(&peer_addr);
if let Some((msg, token)) = unsent_user_msg {
let _ = c.event_tx.send(Event::UnsentUserMessage {
peer_addr,
msg,
token,
});
}
});
}
#[inline]
pub fn handle_send_success(peer_addr: SocketAddr, sent_user_msg: Option<(bytes::Bytes, Token)>) {
ctx_mut(|c| {
if let Some((msg, token)) = sent_user_msg {
let _ = c.event_tx.send(Event::SentUserMessage {
peer_addr,
msg,
token,
});
}
});
}
pub fn read_from_disk<D>(file_path: &Path) -> R<D>
where
D: DeserializeOwned,
{
Ok(File::open(file_path)
.map_err(Into::into)
.map(BufReader::new)
.and_then(|mut rdr| bincode::deserialize_from(&mut rdr))?)
}
pub fn write_to_disk<S>(file_path: &Path, s: &S) -> R<()>
where
S: Serialize,
{
File::create(file_path)
.map_err(Into::into)
.map(BufWriter::new)
.and_then(|mut rdr| bincode::serialize_into(&mut rdr, s))?;
Ok(())
}