use serde::{Deserialize, Serialize};
use super::knowledge::ProposalState;
use super::{require_schema, validate_id, validate_text};
use crate::ValidationError;
pub const PROPOSAL_CONFIRM_SCHEMA: &str = "leanctx.hive.proposal-confirm/v1";
pub const PROPOSAL_CONFIRM_ACK_SCHEMA: &str = "leanctx.hive.proposal-confirm-ack/v1";
pub const MAX_CONFIRMATIONS: u32 = 5;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConfirmationCount {
DistinctSessions,
IndependentOwners,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AutoMergeV1 {
pub confirmations: u32,
pub counts: ConfirmationCount,
}
impl AutoMergeV1 {
pub fn validate(&self) -> Result<(), ValidationError> {
if !(1..=MAX_CONFIRMATIONS).contains(&self.confirmations)
|| self.counts == ConfirmationCount::Unknown
{
return Err(ValidationError::new(
"auto_merge is 1-5 confirmations of a known kind",
));
}
Ok(())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConfirmVerdict {
Confirm,
Object,
#[serde(other)]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ProposalConfirmV1 {
pub schema: String,
pub session_ref: String,
pub verdict: ConfirmVerdict,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
impl ProposalConfirmV1 {
pub fn validate(&self) -> Result<(), ValidationError> {
require_schema(&self.schema, PROPOSAL_CONFIRM_SCHEMA)?;
validate_id(&self.session_ref, "session_ref")?;
if self.verdict == ConfirmVerdict::Unknown {
return Err(ValidationError::new("verdict is confirm or object"));
}
if let Some(reason) = &self.reason {
validate_text(reason, 500, "reason", true)?;
}
Ok(())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ProposalConfirmAckV1 {
pub schema: String,
pub number: u64,
pub confirmations: u32,
pub required: u32,
pub state: ProposalState,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub merged_revision: Option<u64>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub objected: bool,
}
impl ProposalConfirmAckV1 {
pub fn validate(&self) -> Result<(), ValidationError> {
require_schema(&self.schema, PROPOSAL_CONFIRM_ACK_SCHEMA)?;
if (self.state == ProposalState::Merged) != self.merged_revision.is_some() {
return Err(ValidationError::new(
"merged_revision comes exactly with a merged proposal",
));
}
Ok(())
}
}