1use std::io;
2
3use crate::MicroDB;
4
5use super::{ComObj, Path, RawObj};
6
7impl<T, E> RawObj for Result<T, E>
8where
9 T: RawObj,
10 E: RawObj,
11{
12 fn to_db(self) -> Vec<u8> {
13 let mut v = Vec::new();
14 match self {
15 Ok(x) => {
16 v.push(1);
17 v.append(&mut x.to_db());
18 }
19 Err(x) => {
20 v.push(0);
21 v.append(&mut x.to_db());
22 }
23 }
24 v
25 }
26
27 fn from_db(mut x: Vec<u8>) -> Option<Self> {
28 if x.is_empty() {
29 return None;
30 }
31 if x[0] == 0 && x.len() == 1 {
32 x.remove(0);
33 return E::from_db(x).map(|x| Err(x));
34 }
35 if x[0] == 1 {
36 x.remove(0);
37 return T::from_db(x).map(|x| Ok(x));
38 }
39 None
40 }
41}
42
43impl<T, E> ComObj for Result<T, E>
44where
45 T: ComObj,
46 E: ComObj,
47{
48 fn to_db<P: Path>(self, path: P, db: &MicroDB) -> Result<(), io::Error> {
49 db.set_raw(path.sub_path("type"), self.is_ok())?;
50 match self {
51 Ok(x) => db.set_com(path.sub_path("data"), x),
52 Err(x) => db.set_com(path.sub_path("data"), x),
53 }
54 }
55
56 fn remove<P: Path>(path: P, db: &MicroDB) -> Result<(), io::Error> {
57 db.remove_raw(path.sub_path("type"))?;
58 db.remove(path.sub_path("data"))?;
59 Ok(())
60 }
61
62 fn from_db<P: Path>(path: P, db: &MicroDB) -> Result<Option<Self>, io::Error> {
63 if let Some(x) = db.get_raw(path.sub_path("type"))? {
64 if x {
65 if let Some(data) = db.get_com(path.sub_path("data"))? {
66 Ok(Some(Ok(data)))
68 } else {
69 Ok(None)
71 }
72 } else if let Some(data) = db.get_com(path.sub_path("data"))? {
73 Ok(Some(Err(data)))
75 } else {
76 Ok(None)
78 }
79 } else {
80 Ok(None)
82 }
83 }
84
85 fn paths<P: Path>(path: P, _db: &MicroDB) -> Result<Vec<String>, io::Error> {
86 Ok(vec![path.sub_path("type"), path.sub_path("data")])
87 }
88}