1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Serde serializer/deserializer for [stratum v2][Sv2] implemented following [serde tutorial][tutorial]
//!
//! ```txt
//! SERDE    <-> Sv2
//! bool     <-> BOOL
//! u8       <-> U8
//! u16      <-> U16
//! U24      <-> U24
//! u32      <-> u32
//! f32      <-> f32 // not in the spec but used
//! u64      <-> u64 // not in the spec but used
//! U256     <-> U256
//! String   <-> STRO_255
//! Signature<-> SIGNATURE
//! B032     <-> B0_32 // not in the spec but used
//! B032     <-> STR0_32 // not in the spec but used
//! B0255    <-> B0_255
//! B064K    <-> B0_64K
//! B016M    <-> B0_16M
//! [u8]     <-> BYTES
//! Pubkey   <-> PUBKEY
//! Seq0255  <-> SEQ0_255[T]
//! Seq064K  <-> SEQ0_64K[T]
//! ```
//! Serilalizer and Deserializer are implemented using slices in order to reduce copies:
//!
//! ## Fixed length primitives:
//! Each fixed length Sv2 primitive type when deserialized contains a view in the input buffer so
//! no copy is needed to deserialize raw bytes.
//!
//! ## Non fixed legth primitives
//! Non fixed length primitives can be diveded in strings, byte sequences and general sequences.
//!
//! ### Strings
//! Strings are automatically handled by Serde
//!
//! ### Generic sequences
//! Non byte sequences `SEQ0_255[T]` and  `SEQ0_64K[T]` are implemented as a
//! struct that contains two optional field:
//! * an optional view in the input buffer
//! * an optional slice of T
//!
//! When the sequence is constructed from a serialized message we just get a view in the input
//! buffer and no data is copyed.
//!
//! When the sequence is constructed from [T] the sequnce can safely point to them without
//! transmute.
//!
//! ### Bytes sequences
//! Byte sequences can be limited length sequences or unlimited length sequences, the latter are
//! automatically handled by Serde.
//! Limited length byte sequences are not implemented as a specific new type of generic sequences cause:
//! * For the rust type system a serialized byte array and a deserialized byte array are the same
//!   thing, that is not true for generic sequences.
//! * In order to not copy data around generic sequences need to be implemented as struct containing
//!   two optional field, a slice of byte and a slice of T.
//! * This dicotomy is not needed for byte sequences so they are implemented as specific smaller
//! struct.
//!
//! ## Why not rkyv?
//! [rkyv][rkyv1] is a a zero-copy deserialization framework for Rust. I do not know rkyv but it
//! seems that the objective of this library could have been readched with less effort and
//! [better][rkyv2] using rykv instad then serder.
//!
//! Btw Serde is like standard for rust code, very safe and stable. The deserialization/serialization
//! part will be in the code that need to be added to bitcoin core, so it must use the most safe and
//! stable option. That do not exclude that a serialization/deserialization backend can be implemented
//! with rykv and then used by the subprotocols crates via a conditional compilation flag!
//!
//! [Sv2]: https://docs.google.com/document/d/1FadCWj-57dvhxsnFM_7X806qyvhR0u3i85607bGHxvg/edit
//! [tutorial]: https://serde.rs/data-format.html
//! [rkyv1]: https://docs.rs/rkyv/0.4.3/rkyv
//! [rkyv2]: https://davidkoloski.me/blog/rkyv-is-faster-than/

#![no_std]

#[macro_use]
extern crate alloc;

mod de;
mod error;
mod primitives;
mod ser;

pub use de::{from_bytes, Deserializer};
pub use error::{Error, Result};
pub use primitives::{
    Bool, Bytes, GetSize, Pubkey, Seq0255, Seq064K, ShortTxId, Signature, Str0255, Sv2Option,
    B016M, B0255, B032, B064K, U16, U24, U256, U32, U64, U8,
};
pub use ser::{to_bytes, to_writer, Serializer};

impl GetSize for buffer_sv2::Slice {
    fn get_size(&self) -> usize {
        self.len()
    }
}