pub mod exemption;
pub mod key;
use alloc::boxed::Box;
use alloc::vec::Vec;
pub use exemption::Exemption;
pub use key::{WitnessKey, WitnessKeyed};
use crate::fact::FactGroup;
use crate::pass::AnalysisId;
use vize_l0::Span;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct WitnessLink {
pub group: AnalysisId,
pub span: Span,
pub key: WitnessKey,
}
impl WitnessLink {
#[must_use]
pub fn new(group: AnalysisId, span: Span, key: WitnessKey) -> Self {
Self { group, span, key }
}
#[must_use]
pub fn of<G: FactGroup<Key: WitnessKeyed>>(key: &G::Key, span: Span) -> Self {
Self::new(G::ID, span, key.to_witness_key())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct WitnessChain {
links: Box<[WitnessLink]>,
}
impl WitnessChain {
#[must_use]
pub fn new(first: WitnessLink) -> Self {
Self {
links: Box::new([first]),
}
}
#[must_use]
pub fn then(self, link: WitnessLink) -> Self {
let mut links = Vec::from(self.links);
links.push(link);
Self {
links: links.into_boxed_slice(),
}
}
#[must_use]
pub fn from_links(links: Vec<WitnessLink>) -> Option<Self> {
(!links.is_empty()).then(|| Self {
links: links.into_boxed_slice(),
})
}
#[must_use]
pub fn links(&self) -> &[WitnessLink] {
&self.links
}
#[must_use]
pub fn first(&self) -> &WitnessLink {
static UNREACHED: WitnessLink = WitnessLink {
group: AnalysisId::new(0),
span: Span::new(0, 0),
key: WitnessKey::Artifact,
};
self.links.first().unwrap_or(&UNREACHED)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Witness {
Proven(WitnessChain),
LegacyExempt(&'static Exemption),
}