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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! An encoder for bencode. Guarantees that the output string is valid bencode
//!
//! # Encoding a structure
//!
//! The easiest way to encode a structure is to implement [`ToBencode`] for it. For most structures,
//! this should be very simple:
//!
//! ```
//! # use bendy::encoding::{ToBencode, SingleItemEncoder, Error};
//!
//! struct Message {
//! foo: i32,
//! bar: String,
//! }
//!
//! impl ToBencode for Message {
//! // Atoms have depth zero. The struct wrapper adds one level to that
//! const MAX_DEPTH: usize = 1;
//!
//! fn encode(&self, encoder: SingleItemEncoder) -> Result<(), Error> {
//! encoder.emit_dict(|mut e| {
//! // Use e to emit the values
//! e.emit_pair(b"bar", &self.bar)?;
//! e.emit_pair(b"foo", &self.foo)
//! })?;
//! Ok(())
//! }
//! }
//! #
//! # fn main() -> Result<(), Error> {
//! # let message = Message{
//! # foo: 1,
//! # bar: "quux".to_string(),
//! # };
//! #
//! # message.to_bencode().map(|_| ())
//! # }
//! ```
//!
//! Then, messages can be serialized using [`ToBencode::to_bencode`]:
//!
//! ```
//! # use bendy::encoding::{ToBencode, SingleItemEncoder, Error};
//! #
//! # struct Message {
//! # foo: i32,
//! # bar: String,
//! # }
//! #
//! # impl ToBencode for Message {
//! # // Atoms have depth zero. The struct wrapper adds one level to that
//! # const MAX_DEPTH: usize = 1;
//! #
//! # fn encode(&self, encoder: SingleItemEncoder) -> Result<(), Error> {
//! # encoder.emit_dict(|mut e| {
//! # // Use e to emit the values. They must be in sorted order here.
//! # // If sorting the dict first is annoying, you can also use
//! # // encoder.emit_and_sort_dict
//! # e.emit_pair(b"bar", &self.bar)?;
//! # e.emit_pair(b"foo", &self.foo)
//! # })?;
//! # Ok(())
//! # }
//! # }
//! #
//! # fn main() -> Result<(), Error> {
//! let message = Message {
//! foo: 1,
//! bar: "quux".to_string(),
//! };
//!
//! message.to_bencode()
//! # .map(|_| ())
//! # }
//! ```
//!
//! Most primitive types already implement [`ToBencode`].
//!
//! # Nesting depth limits
//!
//! To allow this to be used on limited platforms, all implementations of [`ToBencode`] include a
//! maximum nesting depth. Atoms (integers and byte strings) are considered to have depth 0. An
//! object (a list or dict) containing only atoms has depth 1, and in general, an object has a depth
//! equal to the depth of its deepest member plus one.
//!
//! ## Dynamic depth
//!
//! In some cases, an object doesn't have a statically known depth. For example, ASTs may be
//! arbitrarily nested. Such objects should have `MAX_DEPTH` set to 0, and callers should construct
//! the Encoder manually, adding an appropriate buffer for the depth:
//!
//! ```
//! # use bendy::encoding::{ToBencode, Encoder, Error};
//! #
//! # type ObjectType = u32;
//! # static OBJECT: u32 = 0;
//! #
//! # fn main() -> Result<(), Error> {
//! let mut encoder = Encoder::new().with_max_depth(ObjectType::MAX_DEPTH + 10);
//!
//! encoder.emit(OBJECT)?;
//! encoder.get_output()
//! # .map_err(Error::from)
//! # .map(|_| ()) // ignore a success return value
//! # }
//! ```
//!
//! # Error handling
//!
//! Once an error occurs during encoding, all future calls to the same encoding stream will fail
//! early with the same error. It is not defined whether any callback or implementation of
//! [`ToBencode::encode`] is called before returning an error; such callbacks should
//! respond to failure by bailing out as quickly as possible.
//!
//! Not all values in [`Error`] can be caused by an encoding operation. Specifically, you only need
//! to worry about [`UnsortedKeys`] and [`NestingTooDeep`].
//!
//! [`ToBencode::encode`]: self::ToBencode::encode
//! [`UnsortedKeys`]: self::Error#UnsortedKeys
//! [`NestingTooDeep`]: self::Error#NestingTooDeep
pub use ;