Skip to main content

Half

Enum Half 

Source
pub enum Half<T> {
    Consulted {
        observed_at: u64,
        items: Vec<T>,
    },
    NotConsulted {
        observed_at: u64,
    },
}
Expand description

One collection a responder either consulted — and can therefore answer for — or did not: dig-rewards-coin SPEC §12.5 clause 6.

§Why the items live INSIDE the variant

Clause 6: “the absence MUST be surfaced, not swallowed”, and it “MUST be dated by an observed_at and MUST NOT be presented as a bare zero”. A bare claimable: [] cannot tell an operator apart “I looked and I hold no mirror claims” from “nothing looked” — a funder-only responder emitting the empty vector reads as the former while meaning the latter.

An observation carried beside its collection would leave {"outcome": "not_consulted", "items": [seven things]} expressible, forbidden only by prose. Folding the items into Consulted makes that contradiction unconstructible in Rust and unparseable on the wire: the arm that says nothing looked has no field to put items in, and the arm that carries items has already said it looked. A partially consulted half, if this crate ever needs one, is a third arm rather than a new convention layered over the same two fields.

§What it deliberately cannot say

It describes the responder’s own consultation of the collection, never a chain fact about any one member. Clause 7 forbids a consumer reconstructing “never admitted” from “evicted after settlement”, and there is no arm, reason code or per-member record here that could carry that split: after a Consulted read, a distributor the peer was never admitted to and one it was evicted from are both simply absent from items, exactly as before.

This does not discharge clause 6’s per-member dated absence, which needs a field this wire does not yet carry. What it closes is the per-collection consultation record.

§Relation to absence_established

AvailabilityAnswer::absence_established is this crate’s earlier, weaker expression of the same idea: a marker beside the data, so “absence not established, and here are seven items” stays representable and is forbidden only by prose. Half is the intended direction for new shapes. AvailabilityAnswer keeps its form because it has shipped consumers; it is not a second pattern to copy.

§Fail-closed

Matching ProverState: internally tagged on outcome, no #[serde(other)], no Default, no skip_serializing_if, and observed_at required in every arm. An unknown or missing outcome, or a missing date, is a hard parse error rather than a silently coerced “consulted”.

use dig_rpc_protocol::types::Half;

let looked: Half<u32> = Half::Consulted { observed_at: 1_700, items: vec![] };
let did_not: Half<u32> = Half::NotConsulted { observed_at: 1_700 };
assert_eq!(looked.items(), Some(&[][..]));
assert_eq!(did_not.items(), None);
assert_eq!(did_not.observed_at(), 1_700);

Variants§

§

Consulted

The collection WAS consulted, and items is its complete answer as of observed_at (Unix seconds). An empty items here means “none”, and the reader derives staleness itself from observed_at.

Fields

§observed_at: u64

Unix seconds the collection was read.

§items: Vec<T>

The complete answer as of observed_at; empty means “none”.

§

NotConsulted

The collection was NOT consulted as of observed_at (Unix seconds): nothing looked, so there is no answer here to read as “none”.

Fields

§observed_at: u64

Unix seconds this answer was assembled without consulting the collection.

Implementations§

Source§

impl<T> Half<T>

Source

pub fn observed_at(&self) -> u64

The Unix seconds this half was observed — present in both arms, so a reader always has a staleness anchor.

Source

pub fn items(&self) -> Option<&[T]>

The consulted answer, or None when nothing looked.

Some(&[]) means “consulted, and there are none”; None means “not consulted” — the distinction a bare Vec cannot make.

Trait Implementations§

Source§

impl<T: Clone> Clone for Half<T>

Source§

fn clone(&self) -> Half<T>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for Half<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, T> Deserialize<'de> for Half<T>
where T: Deserialize<'de>,

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T: Eq> Eq for Half<T>

Source§

impl<T: PartialEq> PartialEq for Half<T>

Source§

fn eq(&self, other: &Half<T>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<T> Serialize for Half<T>
where T: Serialize,

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<T: PartialEq> StructuralPartialEq for Half<T>

Auto Trait Implementations§

§

impl<T> Freeze for Half<T>
where Vec<T>: Freeze,

§

impl<T> RefUnwindSafe for Half<T>
where Vec<T>: RefUnwindSafe,

§

impl<T> Send for Half<T>
where Vec<T>: Send,

§

impl<T> Sync for Half<T>
where Vec<T>: Sync,

§

impl<T> Unpin for Half<T>
where Vec<T>: Unpin,

§

impl<T> UnsafeUnpin for Half<T>
where Vec<T>: UnsafeUnpin,

§

impl<T> UnwindSafe for Half<T>
where Vec<T>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.