use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::path::Path;
use miden_protocol::block::BlockNumber;
use miden_protocol::note::{Note, NoteDetails, NoteId, NoteInclusionProof, NoteTag};
use crate::{ConversionError, DecodeMessageExt, proto};
#[cfg(test)]
mod tests;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct NoteSyncHint {
after_block_num: BlockNumber,
tag: NoteTag,
}
impl NoteSyncHint {
pub fn new(after_block_num: BlockNumber, tag: NoteTag) -> Self {
Self { after_block_num, tag }
}
pub fn after_block_num(&self) -> BlockNumber {
self.after_block_num
}
pub fn tag(&self) -> NoteTag {
self.tag
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[allow(clippy::large_enum_variant)]
pub enum NoteFile {
NoteId(NoteId),
ExpectedNote {
details: NoteDetails,
sync_hint: NoteSyncHint,
},
Committed { note: Note, proof: NoteInclusionProof },
}
impl NoteFile {
pub fn to_bytes(&self) -> Vec<u8> {
prost::Message::encode_to_vec(&proto::note_file::NoteFile::from(self))
}
pub fn try_from_bytes(bytes: &[u8]) -> Result<Self, NoteFileError> {
<proto::note_file::NoteFile as prost::Message>::decode(bytes)
.map_err(|error| NoteFileError::Decode(ConversionError::new(error)))?
.decode_and_verify()
.map_err(NoteFileError::Decode)
}
#[cfg(feature = "std")]
pub fn write(&self, path: impl AsRef<Path>) -> Result<(), NoteFileError> {
std::fs::write(path, self.to_bytes()).map_err(NoteFileError::Io)
}
#[cfg(feature = "std")]
pub fn read(path: impl AsRef<Path>) -> Result<Self, NoteFileError> {
let bytes = std::fs::read(path).map_err(NoteFileError::Io)?;
Self::try_from_bytes(&bytes)
}
}
impl From<Note> for NoteFile {
fn from(note: Note) -> Self {
let (assets, metadata, recipient, _attachments) = note.into_parts();
NoteFile::ExpectedNote {
details: NoteDetails::new(assets, recipient),
sync_hint: NoteSyncHint::new(0.into(), metadata.tag()),
}
}
}
impl From<NoteId> for NoteFile {
fn from(note_id: NoteId) -> Self {
NoteFile::NoteId(note_id)
}
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum NoteFileError {
#[error("failed to decode the note file")]
Decode(#[source] ConversionError),
#[cfg(feature = "std")]
#[error("failed to read or write the note file")]
Io(#[source] std::io::Error),
}