pub enum RefRejection {
Cas {
name: String,
expected: Observed,
actual: Observed,
},
Locked {
name: String,
},
}Expand description
The typed ref rejection, re-exported so a consumer of this crate reaches it
without also naming the contract crate. RefRejection::of(&err) is the only
sanctioned way to ask whether a ref write lost a race — never a message.
Why a ref write was refused, typed.
§Why this exists at all
Error::is_cas_failure() / is_lock_contention() died with RefStore, and
receive-pack has to tell a client which ref lost the race and what was
there instead — never by sniffing an error string. gunnar-store’s
error.rs records the loss verbatim: this type “used to carry
RefCas { name, expected, actual } and the Observed three-state beside
it”. This is that, restored, in the one crate both backends already share.
§How it travels, and why the crate is still anyhow-only
The trait methods keep returning anyhow::Result, so no signature in the
frozen contract changes and no caller is forced to match on a storage error
it does not care about. This type implements std::error::Error by hand —
no thiserror, no new dependency — so a backend raises it with
anyhow::Error::new(rejection) and a caller that does care recovers it
with RefRejection::of. The tiny-crate property is about not forcing one
backend’s dependencies onto the other; it was never about refusing to name
this crate’s own errors.
§The two variants, and why Locked is one of them
From the gix arm’s classifier, whose comment is the argument: a lock this
writer could not take is “TYPED, not a Backend: it is transient and
the one control-document writer retries it. Left as an opaque backend error
it read to a caller as a broken disk.”
Variants§
Cas
A compare-and-swap lost: name did not hold what the caller expected,
and nothing was written.
expected is the caller’s claim (Observed::Nothing for a
must-not-exist create); actual is what the backend found.
Locked
A lock on name this writer could not take. Transient — the caller
retries. Not a fault, and specifically not a broken disk.
Implementations§
Source§impl RefRejection
impl RefRejection
Sourcepub fn is_cas_failure(&self) -> bool
pub fn is_cas_failure(&self) -> bool
“Another push beat you to it” — a lost race, not a fault.
Sourcepub fn is_lock_contention(&self) -> bool
pub fn is_lock_contention(&self) -> bool
“Try again” — transient contention on the one writer.
Sourcepub fn of(err: &Error) -> Option<&RefRejection>
pub fn of(err: &Error) -> Option<&RefRejection>
Recover a rejection from an anyhow::Error a backend raised.
This is the only sanctioned way to ask, and it is a named function so
that no caller ever spells downcast_ref — or, worse, matches on the
message text. It walks the context chain, so a backend is free to add
.context(..) above the rejection without hiding it.
Trait Implementations§
Source§impl Clone for RefRejection
impl Clone for RefRejection
Source§fn clone(&self) -> RefRejection
fn clone(&self) -> RefRejection
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for RefRejection
impl Debug for RefRejection
Source§impl Display for RefRejection
impl Display for RefRejection
impl Eq for RefRejection
Source§impl Error for RefRejection
impl Error for RefRejection
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl PartialEq for RefRejection
impl PartialEq for RefRejection
impl StructuralPartialEq for RefRejection
Auto Trait Implementations§
impl Freeze for RefRejection
impl RefUnwindSafe for RefRejection
impl Send for RefRejection
impl Sync for RefRejection
impl Unpin for RefRejection
impl UnsafeUnpin for RefRejection
impl UnwindSafe for RefRejection
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.