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
use hdk::prelude::*;
pub type EntryAndHash<T> = (T, HeaderHash, EntryHash);
pub type OptionEntryAndHash<T> = Option<EntryAndHash<T>>;
fn get_header_hash(signed_header_hashed: element::SignedHeaderHashed) -> HeaderHash {
signed_header_hashed.header_hashed().as_hash().to_owned()
}
pub fn get_latest_for_entry<T: TryFrom<SerializedBytes, Error = SerializedBytesError>>(
entry_hash: EntryHash,
get_options: GetOptions,
) -> ExternResult<OptionEntryAndHash<T>> {
let maybe_latest_header_hash = match get_details(entry_hash.clone(), get_options.clone())? {
Some(Details::Entry(details)) => match details.entry_dht_status {
metadata::EntryDhtStatus::Live => match details.updates.len() {
0 => Some(get_header_hash(details.headers.first().unwrap().to_owned())),
_ => {
let mut sortlist = details.updates.to_vec();
sortlist.sort_by_key(|update| update.header().timestamp().0);
let last = sortlist.last().unwrap().to_owned();
Some(get_header_hash(last))
}
},
metadata::EntryDhtStatus::Dead => None,
_ => None,
},
_ => None,
};
match maybe_latest_header_hash {
Some(latest_header_hash) => match get(latest_header_hash, get_options)? {
Some(element) => match element.entry().to_app_option::<T>()? {
Some(entry) => Ok(Some((
entry,
match element.header() {
Header::Update(update) => update.original_header_address.clone(),
Header::Create(_) => element.header_address().clone(),
_ => unreachable!("Can't have returned a header for a nonexistent entry"),
},
element.header().entry_hash().unwrap().to_owned(),
))),
None => Ok(None),
},
None => Ok(None),
},
None => Ok(None),
}
}
pub fn fetch_links<
EntryType: TryFrom<SerializedBytes, Error = SerializedBytesError>,
WireEntry: From<EntryAndHash<EntryType>>,
>(
entry_hash: EntryHash,
get_options: GetOptions,
) -> Result<Vec<WireEntry>, WasmError> {
Ok(get_links(entry_hash, None)?
.into_inner()
.into_iter()
.map(|link: link::Link| {
get_latest_for_entry::<EntryType>(link.target.clone(), get_options.clone())
})
.filter_map(Result::ok)
.filter_map(|x| x)
.map(|x| WireEntry::from(x))
.collect())
}