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
98
99
100
101
102
103
//! # Nestle
//!
//! Encode/decode arbitrary nested tree-structured data with a single
//! integer.
//!
//! ## Usage
//!
//! Simply use the [Nestle](derives::Nestle) derive macro on your enum or struct.
//!
//! If the width of the top-level type is exceeded, an error will be
//! returned at the point of encoding.
//!
//! ```
//! # use nestle::core::Nestle;
//! # use nestle::derives::Nestle;
//! // This is the top-level type, so it should be 64 bits wide. It uses
//! // `repr(i16)` therefore occupies 16 bits, leaving 48 bits for the
//! // descendants.
//! #[derive(Nestle)]
//! # #[derive(Debug, PartialEq)]
//! #[nestle(width = 64)]
//! #[repr(i16)]
//! enum Instrument {
//! Spot(CurrencyPair) = 1,
//! Options(Options) = 2,
//! PerpetualFutures(CurrencyPair) = 3,
//! }
//!
//! // This type is 48 bits wide, so it can be encoded as a descendant of
//! // `Instrument`.
//! #[derive(Nestle)]
//! # #[derive(Debug, PartialEq)]
//! #[nestle(width = 48)]
//! struct Options {
//! expiry: u16,
//! pair: CurrencyPair,
//! }
//!
//! // This type doesn't use all the available space, which is fine.
//! #[derive(Nestle)]
//! # #[derive(Debug, PartialEq)]
//! #[nestle(width = 32)]
//! struct CurrencyPair {
//! base: Currency,
//! quote: Currency,
//! }
//!
//! // The discriminants of this enum will be used to encode the values.
//! #[derive(Nestle)]
//! # #[derive(Debug, PartialEq)]
//! #[repr(i16)]
//! enum Currency {
//! Btc = 1,
//! Eth = 2,
//! Doge = 3,
//! Usd = 4,
//! }
//!
//! # fn main() {
//! let instrument = Instrument::Options(Options {
//! expiry: 365,
//! pair: CurrencyPair {
//! base: Currency::Eth,
//! quote: Currency::Usd,
//! },
//! });
//!
//! let instrument_id = 564517616615428;
//! // This is the unique, semantic identifier for this instrument.
//! assert_eq!(instrument.encode().unwrap(), instrument_id);
//! // It's the result of the discriminants shifted in to the appropriate
//! // bit positions.
//! assert_eq!(
//! instrument.encode().unwrap(),
//! 2 << 48 | 365 << 32 | 2 << 16 | 4
//! );
//!
//! // The decode method will return the original value.
//! assert_eq!(Instrument::decode(instrument_id).unwrap(), instrument);
//! // Ids have semantic meaning, giving them reproducibility and
//! // mathematical properties.
//! assert_eq!(
//! Instrument::decode(instrument_id - 1).unwrap(),
//! Instrument::Options(Options {
//! expiry: 365,
//! pair: CurrencyPair {
//! base: Currency::Eth,
//! quote: Currency::Doge,
//! },
//! })
//! );
//! // The decode method will fail only if the id is not a valid encoding.
//! assert!(Instrument::decode(instrument_id + 1).is_err());
//! # }
//! ```