use core::fmt;
use alloc::string::String;
use alloc::vec::Vec;
use crate::ProofGenerationKey;
use super::{Bundle, Output, Spend, Zip32Derivation};
impl Bundle {
pub fn update_with<F>(&mut self, f: F) -> Result<(), UpdaterError>
where
F: FnOnce(Updater<'_>) -> Result<(), UpdaterError>,
{
f(Updater(self))
}
}
pub struct Updater<'a>(&'a mut Bundle);
impl Updater<'_> {
pub fn bundle(&self) -> &Bundle {
self.0
}
pub fn update_spend_with<F>(&mut self, index: usize, f: F) -> Result<(), UpdaterError>
where
F: FnOnce(SpendUpdater<'_>) -> Result<(), UpdaterError>,
{
f(SpendUpdater(
self.0
.spends
.get_mut(index)
.ok_or(UpdaterError::InvalidIndex)?,
))
}
pub fn update_output_with<F>(&mut self, index: usize, f: F) -> Result<(), UpdaterError>
where
F: FnOnce(OutputUpdater<'_>) -> Result<(), UpdaterError>,
{
f(OutputUpdater(
self.0
.outputs
.get_mut(index)
.ok_or(UpdaterError::InvalidIndex)?,
))
}
}
pub struct SpendUpdater<'a>(&'a mut Spend);
impl SpendUpdater<'_> {
pub fn set_proof_generation_key(
&mut self,
proof_generation_key: ProofGenerationKey,
) -> Result<(), UpdaterError> {
self.0.proof_generation_key = Some(proof_generation_key);
Ok(())
}
pub fn set_zip32_derivation(&mut self, derivation: Zip32Derivation) {
self.0.zip32_derivation = Some(derivation);
}
pub fn set_proprietary(&mut self, key: String, value: Vec<u8>) {
self.0.proprietary.insert(key, value);
}
}
pub struct OutputUpdater<'a>(&'a mut Output);
impl OutputUpdater<'_> {
pub fn set_zip32_derivation(&mut self, derivation: Zip32Derivation) {
self.0.zip32_derivation = Some(derivation);
}
pub fn set_user_address(&mut self, user_address: String) {
self.0.user_address = Some(user_address);
}
pub fn set_proprietary(&mut self, key: String, value: Vec<u8>) {
self.0.proprietary.insert(key, value);
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum UpdaterError {
InvalidIndex,
WrongProofGenerationKey,
}
impl fmt::Display for UpdaterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UpdaterError::InvalidIndex => write!(f, "Spend or output index is out-of-bounds"),
UpdaterError::WrongProofGenerationKey => {
write!(f, "`proof_generation_key` does not own the spent note")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for UpdaterError {}