| |
}
|
| |
|
| |
/// 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> {
|
| |
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 },
|
| - |
}
|
| - |
}
|
| - |
}
|