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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
use PhantomData;
use cratefmt;
use crate;
pub use Peek;
/// [`Bytes`] specific [`Reader`].
pub type BytesReader<'i, E> = ;
/// [`String`] specific [`Reader`].
pub type StringReader<'i, E> = ;
/// Created from and consumes an [`Input`].
///
/// You can only create a [`Reader`] from [`Input`] via [`Input::read_all()`],
/// [`Input::read_partial()`] or [`Input::read_infallible()`].
///
/// See [`BytesReader`] for [`Bytes`] specific functions and [`StringReader`]
/// for [`String`] specific functions.
///
/// # Conventions
///
/// - `take_*` functions _take_ [`Input`] from the reader.
/// - `read_*` functions _read_ a primitive type from the reader and take a
/// description of what it is for.
/// - `peek_*` functions _peek_ either [`Input`] or a primitive type from the
/// reader without effecting its internal state.
/// - `try_*` functions accept a function that can return an error as an
/// argument.
///
/// # Errors
///
/// Functions on `Reader` are designed to provide a panic free interface and if
/// applicable, clearly define the type of error that can can be thown.
///
/// To verify input and optionally return a type from that verification,
/// [`verify()`], [`try_verify()`], [`expect()`], [`try_expect()`] and
/// [`try_expect_external()`] is provided. These functions are the interface for
/// creating errors based off what was expected.
///
/// [`try_expect_external()`] is provided for reading a custom type that does
/// not support a `&mut Reader<'i, I, E>` interface, for example a type
/// implementing `FromStr`.
///
/// [`recover()`] and [`recover_if()`] are provided as an escape hatch when you
/// wish to catch an error and try another branch.
///
/// [`context()`] and [`peek_context()`] are provided to add a [`Context`] to
/// any error thrown inside their scope. This is useful for debugging.
///
/// # Peeking
///
/// Peeking should be used to find the correct path to consume. Values read from
/// peeking should not be used for the resulting type.
///
/// ```
/// use dangerous::{Input, Invalid};
///
/// let input = dangerous::input(b"true");
/// let result: Result<_, Invalid> = input.read_all(|r| {
/// // We use `peek_u8` here because we expect at least one byte.
/// // If we wanted to handle the case when there is no more input left,
/// // for example to provide a default, we would use `peek_u8_opt`.
/// // The below allows us to handle a `RetryRequirement` if the
/// // `Reader` is at the end of the input.
/// r.try_expect("boolean", |r| match r.peek_u8()? {
/// b't' => r.consume(b"true").map(|()| Some(true)),
/// b'f' => r.consume(b"false").map(|()| Some(false)),
/// _ => Ok(None),
/// })
/// });
/// assert!(matches!(result, Ok(true)));
/// ```
///
/// [`Input`]: crate::Input
/// [`Context`]: crate::error::Context
/// [`Input::read_all()`]: crate::Input::read_all()
/// [`Input::read_partial()`]: crate::Input::read_partial()
/// [`Input::read_infallible()`]: crate::Input::read_infallible()
/// [`context()`]: Reader::context()
/// [`peek_context()`]: Reader::peek_context()
/// [`verify()`]: Reader::verify()
/// [`try_verify()`]: Reader::try_verify()
/// [`expect()`]: Reader::expect()
/// [`try_expect()`]: Reader::try_expect()
/// [`try_expect_external()`]: Reader::try_expect_external()
/// [`recover()`]: Reader::recover()
/// [`recover_if()`]: Reader::recover_if()
/// [`RetryRequirement`]: crate::error::RetryRequirement