use saya_types::{
ClaimId, ClaimOrigin, ClaimPayload, ClaimStatus, DatabaseObjectRef, KnowledgeState,
};
#[derive(Debug)]
pub(crate) struct ContractClaim {
pub id: ClaimId,
#[allow(dead_code)]
pub object: DatabaseObjectRef,
pub value: ClaimPayload,
pub source: ClaimOrigin,
pub status: ClaimStatus,
}
impl ContractClaim {
pub(crate) fn from_knowledge_item(item: &saya_store::KnowledgeItem) -> Option<Self> {
let id = ClaimId::parse(&item.id).ok()?;
Some(Self {
id,
object: item.object.clone(),
value: item.value.clone(),
source: item.source,
status: status_from_state(item.state),
})
}
}
pub(crate) fn status_from_state(state: KnowledgeState) -> ClaimStatus {
match state {
KnowledgeState::Active => ClaimStatus::Confirmed,
KnowledgeState::Pending => ClaimStatus::Candidate,
KnowledgeState::Dismissed => ClaimStatus::Rejected,
_ => ClaimStatus::Rejected,
}
}
pub(crate) struct RetrievedContract {
pub object: DatabaseObjectRef,
pub schema_state: ContractSchemaState,
pub claims: Vec<ContractClaim>,
pub conflicts: Vec<ContractConflict>,
pub truncated: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ContractSchemaState {
Current,
NeedsReview,
LiveSchemaUnavailable,
Stale,
}
impl ContractSchemaState {
pub(crate) fn aggregate(self, other: Self) -> Self {
let rank = |state: Self| match state {
Self::Stale => 3,
Self::LiveSchemaUnavailable => 2,
Self::NeedsReview => 1,
Self::Current => 0,
};
if rank(self) >= rank(other) {
self
} else {
other
}
}
}
pub(crate) struct ContractConflict {
pub kind: &'static str,
pub claim_ids: Vec<ClaimId>,
}
pub(crate) struct RecallOutcome {
pub contracts: Vec<RetrievedContract>,
pub diagnostics: RecallDiagnostics,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub(crate) struct RecallDiagnostics {
pub attempted: bool,
pub considered: usize,
pub selected: usize,
pub excluded_by_privacy: usize,
pub excluded_by_status: usize,
pub excluded_by_schema: usize,
pub excluded_by_count_bounds: usize,
pub store_unavailable: bool,
}