dangerous/input/mod.rs
1mod bytes;
2mod maybe;
3mod prefix;
4mod span;
5mod string;
6mod traits;
7
8pub(crate) mod pattern;
9
10pub use self::bytes::Bytes;
11pub use self::maybe::MaybeString;
12pub use self::pattern::Pattern;
13pub use self::span::Span;
14pub use self::string::String;
15pub use self::traits::Input;
16
17pub(crate) use self::prefix::Prefix;
18pub(crate) use self::traits::{BytesLength, IntoInput, Private, PrivateExt};
19
20/// Creates a new `Input` from a byte or string slice.
21///
22/// It is recommended to use this directly from the crate as `dangerous::input()`,
23/// not as an import via `use` as shown below, as you lose the discoverability.
24///
25/// ```
26/// use dangerous::input; // bad
27///
28/// dangerous::input(b"hello"); // do this instead
29/// ```
30#[inline(always)]
31pub fn input<'i, I>(input: I) -> I::Input
32where
33    I: IntoInput<'i>,
34{
35    input.into_input()
36}
37
38///////////////////////////////////////////////////////////////////////////////
39// Bound
40
41/// Indication of whether [`Input`] will change in futher passes.
42///
43/// Used for retry functionality if enabled.
44#[must_use]
45#[derive(Debug, Copy, Clone, Eq, PartialEq)]
46pub enum Bound {
47    /// Both sides of the [`Input`](crate::Input) may change in further passes.
48    None,
49    /// The start of the [`Input`](crate::Input) in further passes will not change.
50    ///
51    /// The end of the [`Input`](crate::Input) may however change in further passes.
52    Start,
53    /// Both sides of the [`Input`](crate::Input) in further passes will not change.
54    StartEnd,
55}
56
57impl Bound {
58    #[inline(always)]
59    pub(crate) fn force_close() -> Self {
60        Bound::StartEnd
61    }
62
63    /// An end is opened when it is detected a `take_consumed` reader could have
64    /// continued.
65    #[inline(always)]
66    pub(crate) fn open_end(self) -> Self {
67        match self {
68            // If at least the start is bound make sure the end is unbound.
69            Bound::StartEnd | Bound::Start => Bound::Start,
70            // If the start is unbound both sides of the input are unbound.
71            Bound::None => Bound::None,
72        }
73    }
74
75    /// An end is closed when a known length of input is sucessfully taken.
76    #[inline(always)]
77    pub(crate) fn close_end(self) -> Self {
78        // We don't care if the input has no bounds. The only place input with
79        // no bounds can originate is when a reader has reached the end of input
80        // and could have consumed more. In other words - input with no bounds
81        // is always empty. A length of zero taken from input with no bounds
82        // will always succeed but the first half will have both sides bound to
83        // prevent deadlocks.
84        let _ = self;
85        Bound::force_close()
86    }
87
88    #[inline(always)]
89    pub(crate) fn for_end(self) -> Self {
90        match self {
91            // If both sides are bounded nothing will change.
92            Bound::StartEnd => Bound::StartEnd,
93            // As we have skipped to the end without checking, we don't know
94            // where the start is, perhaps the true end is not known yet!
95            Bound::Start | Bound::None => Bound::None,
96        }
97    }
98}