use crate::contracts::availability::{SchemaAvailability, SchemaFreshness};
use crate::contracts::conflict::conflicts_for;
use crate::contracts::knowledge_validity::item_validity_for;
use crate::contracts::selection::Candidate;
use crate::contracts::view::{
ContractClaim, ContractSchemaState, RecallDiagnostics, RetrievedContract,
};
use saya_types::ProfileIdentity;
pub(crate) fn assemble(
candidates: &[Candidate],
schemas: &[(ProfileIdentity, SchemaAvailability)],
bounds: super::RecallBounds,
freshness: SchemaFreshness,
diag: &mut RecallDiagnostics,
) -> Vec<RetrievedContract> {
let mut out: Vec<RetrievedContract> = Vec::new();
for candidate in candidates {
if out.len() >= bounds.max_objects {
if let Some(last) = out.last_mut() {
last.truncated = true;
}
for dropped in &candidates[out.len()..] {
diag.excluded_by_count_bounds += dropped.items.len();
}
break;
}
out.push(build_contract(candidate, schemas, bounds, freshness, diag));
}
out
}
fn build_contract(
candidate: &Candidate,
schemas: &[(ProfileIdentity, SchemaAvailability)],
bounds: super::RecallBounds,
freshness: SchemaFreshness,
diag: &mut RecallDiagnostics,
) -> RetrievedContract {
let mut items: Vec<_> = candidate.items.clone();
let mut truncated = false;
if items.len() > bounds.max_claims_per_object {
diag.excluded_by_count_bounds += items.len() - bounds.max_claims_per_object;
items.truncate(bounds.max_claims_per_object);
truncated = true;
}
let live = schemas
.iter()
.find(|(p, _)| p == candidate.object.profile())
.map(|(_, avail)| avail);
let availability = live.unwrap_or(&SchemaAvailability::Missing);
let mut claims: Vec<ContractClaim> = Vec::with_capacity(items.len());
let mut state = ContractSchemaState::Current;
for item in &items {
let validity = item_validity_for(item, availability, freshness);
state = state.aggregate(validity.into());
if let Some(carrier) = ContractClaim::from_knowledge_item(item) {
claims.push(carrier);
}
}
let conflicts = conflicts_for(&claims);
RetrievedContract {
object: candidate.object.clone(),
schema_state: state,
claims,
conflicts,
truncated,
}
}