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
146
147
use std::fmt::{self, Display, Formatter};
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("failed to add a user that already exits")]
UserAlreadyExists,
#[error("operation failed because user `{}` doesn't exist", id)]
NoSuchUser { id: String },
#[error("failed to initialise library at offset `{}`", offset)]
InitFailed { offset: String },
#[error("failed to perform action because user `{}` is locked", id)]
UserNotOpen { id: String },
#[error("bad unlock token (password?) for id `{}`", id)]
UnlockFailed { id: String },
#[error("tried to operate on locked encrypted state: {}", msg)]
LockedState { msg: String },
#[error("tried to unlock user Id `{}` twice", id)]
AlreadyUnlocked { id: String },
#[error("no such path: `{}`", path)]
NoSuchPath { path: String },
#[error("path exists already: {}", path)]
PathExists { path: String },
#[error("failed to load data: `{}`", msg)]
LoadFailed { msg: String },
#[error("failed to sync data: `{}`", msg)]
SyncFailed { msg: String },
#[error("tried to apply Diff of incompatible type")]
BadDiffType,
#[error("a Diff failed to apply: \n{}", msgs)]
BadDiff { msgs: DiffErrors },
#[error(
"can't merge two iterators with different underlying queries: a: '{}', b: '{}'",
q1,
q2
)]
IncompatibleQuery { q1: String, q2: String },
#[doc(hidden)]
#[error("An alexandria internal error occured: `{}`", msg)]
InternalError { msg: String },
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct DiffErrors(Vec<(usize, String)>);
impl DiffErrors {
pub(crate) fn add(mut self, new: Self) -> Self {
let mut ctr = self.0.len();
new.0.into_iter().for_each(|(_, e)| {
self.0.push((ctr, e));
ctr += 1;
});
self
}
pub(crate) fn replace_text<'n, 'o>(self, old: &'o str, new: &'n str) -> Self {
Self(
self.0
.into_iter()
.map(|(i, s)| (i, s.as_str().replace(old, new).into()))
.collect(),
)
}
}
impl Display for DiffErrors {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.0.iter().fold(Ok(()), |res, (num, msg)| {
res.and_then(|_| write!(f, r#"{}: "{}""#, num, msg))
})
}
}
impl From<Vec<(usize, String)>> for DiffErrors {
fn from(vec: Vec<(usize, String)>) -> Self {
Self(vec)
}
}
impl From<(usize, String)> for DiffErrors {
fn from(tup: (usize, String)) -> Self {
Self(vec![tup])
}
}
impl From<DiffErrors> for Error {
fn from(msgs: DiffErrors) -> Self {
Error::BadDiff { msgs }
}
}
impl From<bincode::Error> for Error {
fn from(be: bincode::Error) -> Self {
use bincode::ErrorKind::*;
let msg = match *be {
Io(e) => format!("I/O error: '{}'", e),
SizeLimit => "Payload too large!".into(),
SequenceMustHaveLength => "Internal sequencing error".into(),
_ => "Unknown encoding error".into(),
};
Self::SyncFailed { msg }
}
}
impl From<async_std::io::Error> for Error {
fn from(e: async_std::io::Error) -> Self {
Self::LoadFailed {
msg: format!("{}", e),
}
}
}