1use std::io::{BufRead, Seek};
24use std::marker::PhantomData;
25use std::{fs, io};
26
27use amplify::confinement::{Collection, Confined};
28use amplify::num::u24;
29use amplify::Wrapper;
30
31use super::{DecodeError, DecodeRawLe, VariantName};
32use crate::reader::StreamReader;
33use crate::writer::StreamWriter;
34use crate::{
35 DeserializeError, FieldName, Primitive, SerializeError, Sizing, StrictDumb, StrictEnum,
36 StrictReader, StrictStruct, StrictSum, StrictTuple, StrictType, StrictUnion, StrictWriter,
37};
38
39pub trait TypedParent: Sized {}
40
41pub trait WriteRaw {
42 fn write_raw<const MAX_LEN: usize>(&mut self, bytes: impl AsRef<[u8]>) -> io::Result<()>;
43 fn write_raw_array<const LEN: usize>(&mut self, raw: [u8; LEN]) -> io::Result<()> {
44 self.write_raw::<LEN>(raw)
45 }
46 fn write_raw_len<const MAX_LEN: usize>(&mut self, len: usize) -> io::Result<()> {
47 match MAX_LEN {
48 tiny if tiny <= u8::MAX as usize => self.write_raw_array((len as u8).to_le_bytes()),
49 small if small <= u16::MAX as usize => self.write_raw_array((len as u16).to_le_bytes()),
50 medium if medium <= u24::MAX.into_usize() => {
51 self.write_raw_array((u24::with(len as u32)).to_le_bytes())
52 }
53 large if large <= u32::MAX as usize => self.write_raw_array((len as u32).to_le_bytes()),
54 huge if huge <= u64::MAX as usize => self.write_raw_array((len as u64).to_le_bytes()),
55 _ => unreachable!("confined collections larger than u64::MAX must not exist"),
56 }
57 }
58}
59
60impl<T: WriteRaw> WriteRaw for &mut T {
61 fn write_raw<const MAX_LEN: usize>(&mut self, bytes: impl AsRef<[u8]>) -> io::Result<()> {
62 (*self).write_raw::<MAX_LEN>(bytes)
63 }
64}
65
66#[allow(unused_variables)]
67pub trait TypedWrite: Sized {
68 type TupleWriter: WriteTuple<Parent = Self>;
69 type StructWriter: WriteStruct<Parent = Self>;
70 type UnionDefiner: DefineUnion<Parent = Self>;
71 type RawWriter: WriteRaw;
72
73 #[doc(hidden)]
74 unsafe fn raw_writer(&mut self) -> &mut Self::RawWriter;
75
76 fn write_union<T: StrictUnion>(
77 self,
78 inner: impl FnOnce(Self::UnionDefiner) -> io::Result<Self>,
79 ) -> io::Result<Self>;
80 fn write_enum<T: StrictEnum>(self, value: T) -> io::Result<Self>
81 where u8: From<T>;
82 fn write_tuple<T: StrictTuple>(
83 self,
84 inner: impl FnOnce(Self::TupleWriter) -> io::Result<Self>,
85 ) -> io::Result<Self>;
86 fn write_struct<T: StrictStruct>(
87 self,
88 inner: impl FnOnce(Self::StructWriter) -> io::Result<Self>,
89 ) -> io::Result<Self>;
90 fn write_newtype<T: StrictTuple>(self, value: &impl StrictEncode) -> io::Result<Self> {
91 self.write_tuple::<T>(|writer| Ok(writer.write_field(value)?.complete()))
92 }
93
94 #[doc(hidden)]
95 unsafe fn register_primitive(self, prim: Primitive) -> Self { self }
96 #[doc(hidden)]
97 unsafe fn register_array(self, ty: &impl StrictEncode, len: u16) -> Self { self }
98 #[doc(hidden)]
99 unsafe fn register_unicode(self, sizing: Sizing) -> Self { self }
100 #[doc(hidden)]
101 #[deprecated(since = "2.3.1", note = "use register_rstring")]
102 unsafe fn register_ascii(self, sizing: Sizing) -> Self {
103 panic!("TypedWrite::register_ascii must not be called; pls see compilation warnings")
104 }
105 #[doc(hidden)]
106 unsafe fn register_rstring(
107 self,
108 c: &impl StrictEncode,
109 c1: &impl StrictEncode,
110 sizing: Sizing,
111 ) -> Self {
112 self
113 }
114 #[doc(hidden)]
115 unsafe fn register_list(self, ty: &impl StrictEncode, sizing: Sizing) -> Self { self }
116 #[doc(hidden)]
117 unsafe fn register_set(self, ty: &impl StrictEncode, sizing: Sizing) -> Self { self }
118 #[doc(hidden)]
119 unsafe fn register_map(
120 self,
121 ket: &impl StrictEncode,
122 ty: &impl StrictEncode,
123 sizing: Sizing,
124 ) -> Self {
125 self
126 }
127
128 #[doc(hidden)]
130 unsafe fn write_string<const MAX_LEN: usize>(
131 mut self,
132 bytes: impl AsRef<[u8]>,
133 ) -> io::Result<Self> {
134 self.raw_writer().write_raw_len::<MAX_LEN>(bytes.as_ref().len())?;
135 self.raw_writer().write_raw::<MAX_LEN>(bytes)?;
136 Ok(self)
137 }
138
139 #[doc(hidden)]
141 unsafe fn write_collection<C: Collection, const MIN_LEN: usize, const MAX_LEN: usize>(
142 mut self,
143 col: &Confined<C, MIN_LEN, MAX_LEN>,
144 ) -> io::Result<Self>
145 where
146 for<'a> &'a C: IntoIterator,
147 for<'a> <&'a C as IntoIterator>::Item: StrictEncode,
148 {
149 self.raw_writer().write_raw_len::<MAX_LEN>(col.len())?;
150 for item in col {
151 self = item.strict_encode(self)?;
152 }
153 Ok(self)
154 }
155
156 }
158
159pub trait ReadRaw {
160 fn read_raw<const MAX_LEN: usize>(&mut self, len: usize) -> io::Result<Vec<u8>>;
161
162 fn read_raw_array<const LEN: usize>(&mut self) -> io::Result<[u8; LEN]>;
163
164 fn read_raw_len<const MAX_LEN: usize>(&mut self) -> Result<usize, DecodeError> {
165 Ok(match MAX_LEN {
166 tiny if tiny <= u8::MAX as usize => u8::decode_raw_le(self)? as usize,
167 small if small <= u16::MAX as usize => u16::decode_raw_le(self)? as usize,
168 medium if medium <= u24::MAX.into_usize() => u24::decode_raw_le(self)?.into_usize(),
169 large if large <= u32::MAX as usize => u32::decode_raw_le(self)? as usize,
170 huge if huge <= u64::MAX as usize => u64::decode_raw_le(self)? as usize,
171 _ => unreachable!("confined collections larger than u64::MAX must not exist"),
172 })
173 }
174}
175
176impl<T: ReadRaw> ReadRaw for &mut T {
177 fn read_raw<const MAX_LEN: usize>(&mut self, len: usize) -> io::Result<Vec<u8>> {
178 (*self).read_raw::<MAX_LEN>(len)
179 }
180
181 fn read_raw_array<const LEN: usize>(&mut self) -> io::Result<[u8; LEN]> {
182 (*self).read_raw_array::<LEN>()
183 }
184}
185
186pub trait TypedRead {
187 type TupleReader<'parent>: ReadTuple
188 where Self: 'parent;
189 type StructReader<'parent>: ReadStruct
190 where Self: 'parent;
191 type UnionReader: ReadUnion;
192 type RawReader: ReadRaw;
193
194 #[doc(hidden)]
195 unsafe fn raw_reader(&mut self) -> &mut Self::RawReader;
196
197 fn read_union<T: StrictUnion>(
198 &mut self,
199 inner: impl FnOnce(VariantName, &mut Self::UnionReader) -> Result<T, DecodeError>,
200 ) -> Result<T, DecodeError>;
201
202 fn read_enum<T: StrictEnum>(&mut self) -> Result<T, DecodeError>
203 where u8: From<T>;
204
205 fn read_tuple<'parent, 'me, T: StrictTuple>(
206 &'me mut self,
207 inner: impl FnOnce(&mut Self::TupleReader<'parent>) -> Result<T, DecodeError>,
208 ) -> Result<T, DecodeError>
209 where
210 Self: 'parent,
211 'me: 'parent;
212
213 fn read_struct<'parent, 'me, T: StrictStruct>(
214 &'me mut self,
215 inner: impl FnOnce(&mut Self::StructReader<'parent>) -> Result<T, DecodeError>,
216 ) -> Result<T, DecodeError>
217 where
218 Self: 'parent,
219 'me: 'parent;
220
221 fn read_newtype<T: StrictTuple + Wrapper>(&mut self) -> Result<T, DecodeError>
222 where T::Inner: StrictDecode {
223 self.read_tuple(|reader| reader.read_field().map(T::from_inner))
224 }
225
226 #[doc(hidden)]
227 unsafe fn read_string<const MAX_LEN: usize>(&mut self) -> Result<Vec<u8>, DecodeError> {
228 let len = self.raw_reader().read_raw_len::<MAX_LEN>()?;
229 self.raw_reader().read_raw::<MAX_LEN>(len).map_err(DecodeError::from)
230 }
231}
232
233pub trait DefineTuple: Sized {
234 type Parent: TypedParent;
235 fn define_field<T: StrictEncode + StrictDumb>(self) -> Self;
236 fn complete(self) -> Self::Parent;
237}
238
239pub trait WriteTuple: Sized {
240 type Parent: TypedParent;
241 fn write_field(self, value: &impl StrictEncode) -> io::Result<Self>;
242 fn complete(self) -> Self::Parent;
243}
244
245pub trait ReadTuple {
246 fn read_field<T: StrictDecode>(&mut self) -> Result<T, DecodeError>;
247}
248
249pub trait DefineStruct: Sized {
250 type Parent: TypedParent;
251 fn define_field<T: StrictEncode + StrictDumb>(self, name: FieldName) -> Self;
252 fn complete(self) -> Self::Parent;
253}
254
255pub trait WriteStruct: Sized {
256 type Parent: TypedParent;
257 fn write_field(self, name: FieldName, value: &impl StrictEncode) -> io::Result<Self>;
258 fn complete(self) -> Self::Parent;
259}
260
261pub trait ReadStruct {
262 fn read_field<T: StrictDecode>(&mut self, field: FieldName) -> Result<T, DecodeError>;
263}
264
265pub trait DefineEnum: Sized {
266 type Parent: TypedWrite;
267 type EnumWriter: WriteEnum<Parent = Self::Parent>;
268 fn define_variant(self, name: VariantName) -> Self;
269 fn complete(self) -> Self::EnumWriter;
270}
271
272pub trait WriteEnum: Sized {
273 type Parent: TypedWrite;
274 fn write_variant(self, name: VariantName) -> io::Result<Self>;
275 fn complete(self) -> Self::Parent;
276}
277
278pub trait DefineUnion: Sized {
279 type Parent: TypedWrite;
280 type TupleDefiner: DefineTuple<Parent = Self>;
281 type StructDefiner: DefineStruct<Parent = Self>;
282 type UnionWriter: WriteUnion<Parent = Self::Parent>;
283
284 fn define_unit(self, name: VariantName) -> Self;
285 fn define_newtype<T: StrictEncode + StrictDumb>(self, name: VariantName) -> Self {
286 self.define_tuple(name, |definer| definer.define_field::<T>().complete())
287 }
288 fn define_tuple(
289 self,
290 name: VariantName,
291 inner: impl FnOnce(Self::TupleDefiner) -> Self,
292 ) -> Self;
293 fn define_struct(
294 self,
295 name: VariantName,
296 inner: impl FnOnce(Self::StructDefiner) -> Self,
297 ) -> Self;
298
299 fn complete(self) -> Self::UnionWriter;
300}
301
302pub trait WriteUnion: Sized {
303 type Parent: TypedWrite;
304 type TupleWriter: WriteTuple<Parent = Self>;
305 type StructWriter: WriteStruct<Parent = Self>;
306
307 fn write_unit(self, name: VariantName) -> io::Result<Self>;
308 fn write_newtype(self, name: VariantName, value: &impl StrictEncode) -> io::Result<Self> {
309 self.write_tuple(name, |writer| Ok(writer.write_field(value)?.complete()))
310 }
311 fn write_tuple(
312 self,
313 name: VariantName,
314 inner: impl FnOnce(Self::TupleWriter) -> io::Result<Self>,
315 ) -> io::Result<Self>;
316 fn write_struct(
317 self,
318 name: VariantName,
319 inner: impl FnOnce(Self::StructWriter) -> io::Result<Self>,
320 ) -> io::Result<Self>;
321
322 fn complete(self) -> Self::Parent;
323}
324
325pub trait ReadUnion: Sized {
326 type TupleReader<'parent>: ReadTuple
327 where Self: 'parent;
328 type StructReader<'parent>: ReadStruct
329 where Self: 'parent;
330
331 fn read_tuple<'parent, 'me, T: StrictSum>(
332 &'me mut self,
333 inner: impl FnOnce(&mut Self::TupleReader<'parent>) -> Result<T, DecodeError>,
334 ) -> Result<T, DecodeError>
335 where
336 Self: 'parent,
337 'me: 'parent;
338
339 fn read_struct<'parent, 'me, T: StrictSum>(
340 &'me mut self,
341 inner: impl FnOnce(&mut Self::StructReader<'parent>) -> Result<T, DecodeError>,
342 ) -> Result<T, DecodeError>
343 where
344 Self: 'parent,
345 'me: 'parent;
346
347 fn read_newtype<T: StrictSum + From<I>, I: StrictDecode>(&mut self) -> Result<T, DecodeError> {
348 self.read_tuple(|reader| reader.read_field::<I>().map(T::from))
349 }
350}
351
352pub trait StrictEncode: StrictType {
353 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W>;
354 fn strict_write(&self, writer: impl WriteRaw) -> io::Result<()> {
355 let w = StrictWriter::with(writer);
356 self.strict_encode(w)?;
357 Ok(())
358 }
359}
360
361pub trait StrictDecode: StrictType {
362 fn strict_decode(reader: &mut impl TypedRead) -> Result<Self, DecodeError>;
363 fn strict_read(reader: impl ReadRaw) -> Result<Self, DecodeError> {
364 let mut r = StrictReader::with(reader);
365 Self::strict_decode(&mut r)
366 }
367}
368
369impl<T: StrictEncode> StrictEncode for &T {
370 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> {
371 (*self).strict_encode(writer)
372 }
373}
374
375impl<T> StrictEncode for PhantomData<T> {
376 fn strict_encode<W: TypedWrite>(&self, writer: W) -> io::Result<W> { Ok(writer) }
377}
378
379impl<T> StrictDecode for PhantomData<T> {
380 fn strict_decode(_reader: &mut impl TypedRead) -> Result<Self, DecodeError> { Ok(default!()) }
381}
382
383pub trait StrictSerialize: StrictEncode {
384 fn strict_serialized_len<const MAX: usize>(&self) -> io::Result<usize> {
385 let counter = StrictWriter::counter::<MAX>();
386 Ok(self.strict_encode(counter)?.unbox().unconfine().count)
387 }
388
389 fn to_strict_serialized<const MAX: usize>(
390 &self,
391 ) -> Result<Confined<Vec<u8>, 0, MAX>, SerializeError> {
392 let ast_data = StrictWriter::in_memory::<MAX>();
393 let data = self.strict_encode(ast_data)?.unbox().unconfine();
394 Confined::<Vec<u8>, 0, MAX>::try_from(data).map_err(SerializeError::from)
395 }
396
397 fn strict_serialize_to_file<const MAX: usize>(
398 &self,
399 path: impl AsRef<std::path::Path>,
400 ) -> Result<(), SerializeError> {
401 let file = fs::File::create(path)?;
402 let file = StrictWriter::with(StreamWriter::new::<MAX>(file));
404 self.strict_encode(file)?;
405 Ok(())
406 }
407}
408
409pub trait StrictDeserialize: StrictDecode {
410 fn from_strict_serialized<const MAX: usize>(
411 ast_data: Confined<Vec<u8>, 0, MAX>,
412 ) -> Result<Self, DeserializeError> {
413 let mut reader = StrictReader::in_memory::<MAX>(ast_data);
414 let me = Self::strict_decode(&mut reader)?;
415 let mut cursor = reader.into_cursor();
416 if !cursor.fill_buf()?.is_empty() {
417 return Err(DeserializeError::DataNotEntirelyConsumed);
418 }
419 Ok(me)
420 }
421
422 fn strict_deserialize_from_file<const MAX: usize>(
423 path: impl AsRef<std::path::Path>,
424 ) -> Result<Self, DeserializeError> {
425 let file = fs::File::open(path)?;
426 let mut reader = StrictReader::with(StreamReader::new::<MAX>(file));
428 let me = Self::strict_decode(&mut reader)?;
429 let mut file = reader.unbox().unconfine();
430 if file.stream_position()? != file.seek(io::SeekFrom::End(0))? {
431 return Err(DeserializeError::DataNotEntirelyConsumed);
432 }
433 Ok(me)
434 }
435}