sapling_crypto/pczt/
updater.rs1use core::fmt;
2
3use alloc::string::String;
4use alloc::vec::Vec;
5
6use crate::ProofGenerationKey;
7
8use super::{Bundle, Output, Spend, Zip32Derivation};
9
10impl Bundle {
11 pub fn update_with<F>(&mut self, f: F) -> Result<(), UpdaterError>
13 where
14 F: FnOnce(Updater<'_>) -> Result<(), UpdaterError>,
15 {
16 f(Updater(self))
17 }
18}
19
20pub struct Updater<'a>(&'a mut Bundle);
22
23impl Updater<'_> {
24 pub fn bundle(&self) -> &Bundle {
26 self.0
27 }
28
29 pub fn update_spend_with<F>(&mut self, index: usize, f: F) -> Result<(), UpdaterError>
32 where
33 F: FnOnce(SpendUpdater<'_>) -> Result<(), UpdaterError>,
34 {
35 f(SpendUpdater(
36 self.0
37 .spends
38 .get_mut(index)
39 .ok_or(UpdaterError::InvalidIndex)?,
40 ))
41 }
42
43 pub fn update_output_with<F>(&mut self, index: usize, f: F) -> Result<(), UpdaterError>
46 where
47 F: FnOnce(OutputUpdater<'_>) -> Result<(), UpdaterError>,
48 {
49 f(OutputUpdater(
50 self.0
51 .outputs
52 .get_mut(index)
53 .ok_or(UpdaterError::InvalidIndex)?,
54 ))
55 }
56}
57
58pub struct SpendUpdater<'a>(&'a mut Spend);
60
61impl SpendUpdater<'_> {
62 pub fn set_proof_generation_key(
66 &mut self,
67 proof_generation_key: ProofGenerationKey,
68 ) -> Result<(), UpdaterError> {
69 self.0.proof_generation_key = Some(proof_generation_key);
71 Ok(())
72 }
73
74 pub fn set_zip32_derivation(&mut self, derivation: Zip32Derivation) {
76 self.0.zip32_derivation = Some(derivation);
77 }
78
79 pub fn set_proprietary(&mut self, key: String, value: Vec<u8>) {
81 self.0.proprietary.insert(key, value);
82 }
83}
84
85pub struct OutputUpdater<'a>(&'a mut Output);
87
88impl OutputUpdater<'_> {
89 pub fn set_zip32_derivation(&mut self, derivation: Zip32Derivation) {
91 self.0.zip32_derivation = Some(derivation);
92 }
93
94 pub fn set_user_address(&mut self, user_address: String) {
96 self.0.user_address = Some(user_address);
97 }
98
99 pub fn set_proprietary(&mut self, key: String, value: Vec<u8>) {
101 self.0.proprietary.insert(key, value);
102 }
103}
104
105#[derive(Debug)]
107#[non_exhaustive]
108pub enum UpdaterError {
109 InvalidIndex,
111 WrongProofGenerationKey,
113}
114
115impl fmt::Display for UpdaterError {
116 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
117 match self {
118 UpdaterError::InvalidIndex => write!(f, "Spend or output index is out-of-bounds"),
119 UpdaterError::WrongProofGenerationKey => {
120 write!(f, "`proof_generation_key` does not own the spent note")
121 }
122 }
123 }
124}
125
126#[cfg(feature = "std")]
127impl std::error::Error for UpdaterError {}