mpl_token_auth_rules/state/v2/constraint/
all.rs1use solana_program::{msg, program_error::ProgramError};
2
3use crate::{
4 error::RuleSetError,
5 state::{try_from_bytes, RuleResult},
6 state::{
7 v2::{Constraint, ConstraintType, RuleV2, HEADER_SECTION, U64_BYTES},
8 Header,
9 },
10};
11
12pub struct All<'a> {
14 pub size: &'a u64,
16 pub rules: Vec<RuleV2<'a>>,
18}
19
20impl<'a> All<'a> {
21 pub fn from_bytes(bytes: &'a [u8]) -> Result<Self, RuleSetError> {
23 let size = try_from_bytes::<u64>(0, U64_BYTES, bytes)?;
24
25 let mut rules = Vec::with_capacity(*size as usize);
26 let mut offset = U64_BYTES;
27
28 for _ in 0..*size {
29 let rule = RuleV2::from_bytes(&bytes[offset..])?;
30 offset += rule.length();
31 rules.push(rule);
32 }
33
34 Ok(Self { size, rules })
35 }
36
37 pub fn serialize(rules: &[&[u8]]) -> Result<Vec<u8>, RuleSetError> {
39 let length = (U64_BYTES
41 + rules
42 .iter()
43 .map(|v| v.len())
44 .reduce(|accum, item| accum + item)
45 .ok_or(RuleSetError::DataIsEmpty)
46 .unwrap()) as u32;
47
48 let mut data = Vec::with_capacity(HEADER_SECTION + length as usize);
49
50 Header::serialize(ConstraintType::All, length, &mut data);
52
53 let size = rules.len() as u64;
56 data.extend(u64::to_le_bytes(size));
57 rules.iter().for_each(|x| data.extend(x.iter()));
59
60 Ok(data)
61 }
62}
63
64impl<'a> Constraint<'a> for All<'a> {
65 fn constraint_type(&self) -> ConstraintType {
66 ConstraintType::All
67 }
68
69 fn validate(
70 &self,
71 accounts: &std::collections::HashMap<
72 solana_program::pubkey::Pubkey,
73 &solana_program::account_info::AccountInfo,
74 >,
75 payload: &crate::payload::Payload,
76 update_rule_state: bool,
77 rule_set_state_pda: &Option<&solana_program::account_info::AccountInfo>,
78 rule_authority: &Option<&solana_program::account_info::AccountInfo>,
79 ) -> RuleResult {
80 msg!("Validating All");
81
82 let mut last: Option<ProgramError> = None;
83
84 for rule in &self.rules {
85 let result = rule.validate(
86 accounts,
87 payload,
88 update_rule_state,
89 rule_set_state_pda,
90 rule_authority,
91 );
92 match result {
94 RuleResult::Success(err) => last = Some(err),
95 _ => return result,
96 }
97 }
98
99 RuleResult::Success(last.unwrap_or_else(|| RuleSetError::UnexpectedRuleSetFailure.into()))
101 }
102}