use alloc::string::String;
use alloc::vec::Vec;
use serde::{Deserialize, Serialize};
use crate::error::CompositionError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PredicateType {
Equality,
Range,
Membership,
Computation,
Existence,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct Predicate {
#[serde(rename = "type")]
pub predicate_type: PredicateType,
pub domain: String,
#[serde(with = "serde_bytes")]
pub body: Vec<u8>,
}
impl Predicate {
pub fn new(
predicate_type: PredicateType,
domain: impl Into<String>,
body: Vec<u8>,
) -> Result<Self, CompositionError> {
let p = Self {
predicate_type,
domain: domain.into(),
body,
};
p.validate_shape()?;
Ok(p)
}
pub fn predicate_type(&self) -> &PredicateType { &self.predicate_type }
pub fn predicate_type_str(&self) -> &str {
match self.predicate_type {
PredicateType::Equality => "equality",
PredicateType::Range => "range",
PredicateType::Membership => "membership",
PredicateType::Computation => "computation",
PredicateType::Existence => "existence",
}
}
pub fn domain(&self) -> &str { &self.domain }
pub fn body(&self) -> &[u8] { &self.body }
pub fn validate_shape(&self) -> Result<(), CompositionError> {
match (&self.predicate_type, self.body.len()) {
(PredicateType::Existence, 0) => Ok(()),
(PredicateType::Existence, _) => Err(CompositionError::Invariant(
"predicate.existence requires an empty body",
)),
(_, 0) => Err(CompositionError::Invariant(
"non-existence predicate requires a non-empty body",
)),
_ => Ok(()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EncodedRange {
pub field: String,
#[serde(with = "serde_bytes")]
pub lower: Vec<u8>,
#[serde(with = "serde_bytes")]
pub upper: Vec<u8>,
#[serde(default, skip_serializing_if = "core::ops::Not::not", rename = "open-lower")]
pub open_lower: bool,
#[serde(default, skip_serializing_if = "core::ops::Not::not", rename = "open-upper")]
pub open_upper: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct EncodedMembership {
#[serde(rename = "set-commitment", with = "serde_bytes")]
pub set_commitment: Vec<u8>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub path: Option<Vec<crate::primitives::subject::SubjectId>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub index: Option<u64>,
}