Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
REVIEW: Rewrite canonical tip resolution
Lorenz Leutgeb committed 2 months ago
commit c00891dcb10f8460cb95de6065db2692c135db8b
parent 6318aa2191e843256829d064ed30b607fbf0f4d3
1 file changed +22 -54
modified crates/radicle-fetch/src/state.rs
@@ -640,61 +640,47 @@ where
    }

    /// Resolve the verified [`Doc`], by choosing a `refs/rad/id` head to
-
    /// resolve with.
+
    /// resolve from.
    ///
-
    /// There are two `refs/rad/id` to possibly choose from:
+
    /// There are two candidate namespaces:
    ///
-
    ///   1. The `refs/rad/id` of the fetching node, if present
-
    ///   2. The `refs/rad/id` of the node being fetched from, if set.
+
    ///   1. Of the fetching node.
+
    ///   2. Of the node being fetched from.
    ///
-
    /// If *neither* of these are present, then `None` is returned.
+
    /// Both might be unset, in this case [`None`] is returned.
    ///
-
    /// If *one or the other* of these are present, then try to load the verified
-
    /// the [`Doc`].
+
    /// If exactly one of the two is set, it is used.
    ///
-
    /// If *both* of these are present, then check which one is the latest
-
    /// update, falling back to the one present in the local repository.
+
    /// Otherwise, the ahead/behind relationship between the two candidates
+
    /// is checked, and (2.) is used if it is ahead of (1.).
    pub fn canonical(&self) -> Result<Option<Doc>, error::Canonical> {
        let tip = self.refname_to_id(refs::REFS_RAD_ID.clone())?;
        let cached_tip = self.canonical_rad_id();
-
        let tip = CanonicalTip::new(tip, cached_tip);

-
        match tip {
-
            CanonicalTip::Neither => Ok(None),
-
            CanonicalTip::Repository(oid) => {
-
                self.verified(oid).map(Some).map_err(error::Canonical::from)
+
        let oid = match (tip, cached_tip) {
+
            (None, None) => {
+
                return Ok(None);
            }
-
            CanonicalTip::Cached(oid) => {
-
                self.verified(oid).map(Some).map_err(error::Canonical::from)
-
            }
-
            CanonicalTip::Both { repository, cached } => {
+
            (Some(oid), None) | (None, Some(oid)) => oid,
+
            (Some(repository), Some(cached)) => {
                let repo = self.handle.repository();
                match repo
                    .backend
                    .graph_ahead_behind(repository.into(), cached.into())
                {
                    Ok((ahead, behind)) => match (ahead, behind) {
-
                        (_, 0) => self
-
                            .verified(repository)
-
                            .map(Some)
-
                            .map_err(error::Canonical::from),
-
                        (0, m) if m > 0 => self
-
                            .verified(cached)
-
                            .map(Some)
-
                            .map_err(error::Canonical::from),
-
                        _ => self
-
                            .verified(repository)
-
                            .map(Some)
-
                            .map_err(error::Canonical::from),
+
                        (0, _) => cached,
+
                        _ => repository,
                    },
-
                    Err(err) if err.code() == radicle::git::raw::ErrorCode::NotFound => self
-
                        .verified(repository)
-
                        .map(Some)
-
                        .map_err(error::Canonical::from),
-
                    Err(err) => Err(error::Canonical::Graph(err)),
+
                    Err(err) if err.code() == radicle::git::raw::ErrorCode::NotFound => repository,
+
                    Err(err) => {
+
                        return Err(error::Canonical::Graph(err));
+
                    }
                }
            }
-
        }
+
        };
+

+
        self.verified(oid).map(Some).map_err(error::Canonical::from)
    }

    pub fn load(&self, remote: &PublicKey) -> Result<Option<SignedRefsAt>, sigrefs::error::Load> {
@@ -782,21 +768,3 @@ where
        Ok(validations)
    }
}
-

-
enum CanonicalTip {
-
    Neither,
-
    Repository(Oid),
-
    Cached(Oid),
-
    Both { repository: Oid, cached: Oid },
-
}
-

-
impl CanonicalTip {
-
    fn new(repository: Option<Oid>, cached: Option<Oid>) -> Self {
-
        match (repository, cached) {
-
            (None, None) => CanonicalTip::Neither,
-
            (None, Some(cached)) => CanonicalTip::Cached(cached),
-
            (Some(repository), None) => CanonicalTip::Repository(repository),
-
            (Some(repository), Some(cached)) => CanonicalTip::Both { repository, cached },
-
        }
-
    }
-
}