1use crate::{
2 alloc::{Allocator, Global},
3 error::{DecodeError, EncodeError},
4};
5use auto_impl::auto_impl;
6use core::ops::RangeBounds;
7
8mod proof;
9pub use proof::{Proof, Version, VersionedProof};
10
11mod imp;
12pub use imp::{Reader, Writer};
13
14pub mod v1;
16
17pub const MAGIC: &[u8; 31] = b"\x00OpenTimestamps\x00\x00Proof\x00\xbf\x89\xe2\xe8\x84\xe8\x92\x94";
19
20pub trait Encoder: Sized {
22 fn encode_byte(&mut self, byte: u8) -> Result<(), EncodeError>;
24
25 fn encode_bytes(&mut self, bytes: impl AsRef<[u8]>) -> Result<(), EncodeError> {
27 let bytes = bytes.as_ref();
28 self.encode(bytes.len())?;
29 self.write_all(bytes)?;
30 Ok(())
31 }
32
33 fn encode_magic(&mut self) -> Result<(), EncodeError> {
35 self.write_all(&MAGIC[..])
36 }
37
38 fn encode(&mut self, value: impl Encode) -> Result<(), EncodeError> {
40 value.encode(self)
41 }
42
43 fn write_all(&mut self, buf: impl AsRef<[u8]>) -> Result<(), EncodeError>;
45}
46
47pub trait Decoder: Sized {
49 fn decode_byte(&mut self) -> Result<u8, DecodeError>;
51
52 fn decode_ranged<T: Decode + PartialOrd>(
54 &mut self,
55 range: impl RangeBounds<T>,
56 ) -> Result<T, DecodeError> {
57 let val: T = self.decode()?;
58 if range.contains(&val) {
59 Ok(val)
60 } else {
61 Err(DecodeError::OutOfRange)
62 }
63 }
64
65 fn assert_magic(&mut self) -> Result<(), DecodeError> {
67 let mut buf = [0u8; MAGIC.len()];
68 self.read_exact(&mut buf)?;
69 if buf == *MAGIC {
70 Ok(())
71 } else {
72 Err(DecodeError::BadMagic)
73 }
74 }
75
76 fn decode<T: Decode>(&mut self) -> Result<T, DecodeError> {
78 T::decode(self)
79 }
80
81 fn decode_trailing<T: Decode>(&mut self) -> Result<Option<T>, DecodeError> {
85 T::decode_trailing(self)
86 }
87
88 fn decode_in<T: DecodeIn<A>, A: Allocator>(&mut self, alloc: A) -> Result<T, DecodeError> {
90 T::decode_in(self, alloc)
91 }
92
93 fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), DecodeError>;
95}
96
97#[auto_impl(&, &mut, Box, Rc, Arc)]
99pub trait Encode {
100 fn encode(&self, writer: &mut impl Encoder) -> Result<(), EncodeError>;
101}
102
103pub trait Decode: Sized {
105 fn decode(decoder: &mut impl Decoder) -> Result<Self, DecodeError>;
106
107 fn decode_trailing(decoder: &mut impl Decoder) -> Result<Option<Self>, DecodeError> {
114 match Self::decode(decoder) {
115 Ok(value) => Ok(Some(value)),
116 Err(DecodeError::UnexpectedEof) => Ok(None),
117 Err(e) => Err(e),
118 }
119 }
120}
121
122pub trait DecodeIn<A: Allocator>: Sized {
124 fn decode_in(decoder: &mut impl Decoder, alloc: A) -> Result<Self, DecodeError>;
126
127 fn decode_trailing(decoder: &mut impl Decoder, alloc: A) -> Result<Option<Self>, DecodeError> {
129 match Self::decode_in(decoder, alloc) {
130 Ok(value) => Ok(Some(value)),
131 Err(DecodeError::UnexpectedEof) => Ok(None),
132 Err(e) => Err(e),
133 }
134 }
135}
136
137impl<T: DecodeIn<Global>> Decode for T {
138 fn decode(decoder: &mut impl Decoder) -> Result<Self, DecodeError> {
139 T::decode_in(decoder, Global)
140 }
141
142 fn decode_trailing(decoder: &mut impl Decoder) -> Result<Option<Self>, DecodeError> {
143 match Self::decode_in(decoder, Global) {
144 Ok(value) => Ok(Some(value)),
145 Err(DecodeError::UnexpectedEof) => Ok(None),
146 Err(e) => Err(e),
147 }
148 }
149}