radicle_cob/object/collaboration/
list.rs

1// Copyright © 2022 The Radicle Link Contributors
2
3use crate::{change_graph::ChangeGraph, CollaborativeObject, Evaluate, Store, TypeName};
4
5use super::error;
6
7/// List a set of [`CollaborativeObject`].
8///
9/// The `storage` is the backing storage for storing
10/// [`crate::Entry`]s at content-addressable locations. Please see
11/// [`Store`] for further information.
12///
13/// The `typename` is the type of objects to be listed.
14pub fn list<T, S>(
15    storage: &S,
16    typename: &TypeName,
17) -> Result<Vec<CollaborativeObject<T>>, error::Retrieve>
18where
19    T: Evaluate<S>,
20    S: Store,
21{
22    let references = storage
23        .types(typename)
24        .map_err(|err| error::Retrieve::Refs { err: Box::new(err) })?;
25    log::trace!(target: "cob", "Loaded {} references", references.len());
26    let mut result = Vec::new();
27    for (oid, tip_refs) in references {
28        log::trace!(target: "cob", "Loading object '{oid}'");
29        let loaded = ChangeGraph::load(storage, tip_refs.iter(), typename, &oid)
30            .map(|graph| graph.evaluate(storage).map_err(error::Retrieve::evaluate));
31
32        match loaded {
33            Some(Ok(obj)) => {
34                log::trace!(target: "cob", "Object '{oid}' found");
35                result.push(obj);
36            }
37            Some(Err(e)) => {
38                log::trace!(target: "cob", "Object '{oid}' failed to load: {e}")
39            }
40            None => {
41                log::trace!(target: "cob", "Object '{oid}' not found");
42            }
43        }
44    }
45    Ok(result)
46}