Skip to main content

radicle_protocol/
fetcher.rs

1use nonempty::NonEmpty;
2use radicle::storage::refs::RefsAt;
3use serde::{Deserialize, Serialize};
4
5pub mod service;
6pub use service::FetcherService;
7
8pub mod state;
9pub use state::{ActiveFetch, Config, FetcherState, MaxQueueSize, Queue, QueueIter, QueuedFetch};
10
11#[cfg(test)]
12mod test;
13
14// TODO(finto): `Service::fetch_refs_at` and the use of `refs_status_of` is a
15// layer above the `Fetcher` where it would perform I/O, mocked out by a trait,
16// to check if there are wants and add a fetch to the Fetcher.
17
18/// Represents references to fetch, in the context of a repository.
19#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
20pub enum RefsToFetch {
21    /// Indicates that all references should be fetched.
22    All,
23    /// Contains a non-empty collection of specific references to fetch.
24    Refs(NonEmpty<RefsAt>),
25}
26
27impl RefsToFetch {
28    /// Merges another `RefsToFetch` into this one, resulting in a new
29    /// `RefsToFetch` that represents the combined set of references to fetch.
30    /// If either `RefsToFetch` is `All`, the result will be `All`. If both are
31    /// `Refs`, their contents will be combined into a single `Refs` variant.
32    pub(super) fn merge(self, other: RefsToFetch) -> Self {
33        match (self, other) {
34            (RefsToFetch::All, _) | (_, RefsToFetch::All) => RefsToFetch::All,
35            (RefsToFetch::Refs(mut ours), RefsToFetch::Refs(theirs)) => {
36                ours.extend(theirs);
37                RefsToFetch::Refs(ours)
38            }
39        }
40    }
41
42    #[cfg(test)]
43    pub fn len(&self) -> Option<std::num::NonZeroUsize> {
44        match self {
45            RefsToFetch::All => None,
46            RefsToFetch::Refs(refs) => std::num::NonZeroUsize::new(refs.len()),
47        }
48    }
49}
50
51impl From<RefsToFetch> for Vec<RefsAt> {
52    fn from(val: RefsToFetch) -> Self {
53        match val {
54            RefsToFetch::All => Vec::new(),
55            RefsToFetch::Refs(refs) => refs.into(),
56        }
57    }
58}
59
60impl From<Vec<RefsAt>> for RefsToFetch {
61    fn from(refs_at: Vec<RefsAt>) -> Self {
62        match NonEmpty::from_vec(refs_at) {
63            Some(refs) => RefsToFetch::Refs(refs),
64            None => RefsToFetch::All,
65        }
66    }
67}