pub struct StreamingPeekableIter<T> { /* private fields */ }
Expand description

Read pack lines one after another, without consuming more than needed from the underlying Read. Flush lines cause the reader to stop producing lines forever, leaving Read at the start of whatever comes next.

This implementation tries hard not to allocate at all which leads to quite some added complexity and plenty of extra memory copies.

Implementations§

Non-IO methods

Available on crate feature blocking-io only.

Read a packet line into the internal buffer and return it.

Returns None if the end of iteration is reached because of one of the following:

  • natural EOF
  • ERR packet line encountered if fail_on_err_lines() is true.
  • A delimiter packet line encountered
Examples found in repository?
src/read/sidebands/blocking_io.rs (line 110)
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
    pub fn read_data_line(&mut self) -> Option<io::Result<Result<PacketLineRef<'_>, crate::decode::Error>>> {
        assert_eq!(
            self.cap, 0,
            "we don't support partial buffers right now - read-line must be used consistently"
        );
        self.parent.read_line()
    }
}

impl<'a, T, F> BufRead for WithSidebands<'a, T, F>
where
    T: io::Read,
    F: FnMut(bool, &[u8]),
{
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        if self.pos >= self.cap {
            let (ofs, cap) = loop {
                let line = match self.parent.read_line() {
                    Some(line) => line?.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?,
                    None => break (0, 0),
                };
                match self.handle_progress.as_mut() {
                    Some(handle_progress) => {
                        let band = line
                            .decode_band()
                            .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
                        const ENCODED_BAND: usize = 1;
                        match band {
                            BandRef::Data(d) => {
                                if d.is_empty() {
                                    continue;
                                }
                                break (U16_HEX_BYTES + ENCODED_BAND, d.len());
                            }
                            BandRef::Progress(d) => {
                                let text = TextRef::from(d).0;
                                handle_progress(false, text);
                            }
                            BandRef::Error(d) => {
                                let text = TextRef::from(d).0;
                                handle_progress(true, text);
                            }
                        };
                    }
                    None => {
                        break match line.as_slice() {
                            Some(d) => (U16_HEX_BYTES, d.len()),
                            None => {
                                return Err(io::Error::new(
                                    io::ErrorKind::UnexpectedEof,
                                    "encountered non-data line in a data-line only context",
                                ))
                            }
                        }
                    }
                }
            };
            self.cap = cap + ofs;
            self.pos = ofs;
        }
        Ok(&self.parent.buf[self.pos..self.cap])
    }
Available on crate feature blocking-io only.

Peek the next packet line without consuming it.

Multiple calls to peek will return the same packet line, if there is one.

Examples found in repository?
src/read/sidebands/blocking_io.rs (line 92)
91
92
93
94
95
96
97
98
    pub fn peek_data_line(&mut self) -> Option<io::Result<Result<&[u8], crate::decode::Error>>> {
        match self.parent.peek_line() {
            Some(Ok(Ok(PacketLineRef::Data(line)))) => Some(Ok(Ok(line))),
            Some(Ok(Err(err))) => Some(Ok(Err(err))),
            Some(Err(err)) => Some(Err(err)),
            _ => None,
        }
    }
Available on crate feature blocking-io only.

Return this instance as implementor of Read assuming side bands to be used in all received packet lines. Each invocation of read_line() returns a packet line.

Progress or error information will be passed to the given handle_progress(is_error, text) function, with is_error: bool being true in case the text is to be interpreted as error.

Please note that side bands need to be negotiated with the server.

Available on crate feature blocking-io only.

Same as as_read_with_sidebands(…), but for channels without side band support.

The type parameter F needs to be configured for this method to be callable using the ‘turbofish’ operator. Use as_read().

Available on crate feature blocking-io only.

Same as as_read_with_sidebands(…), but for channels without side band support.

Due to the preconfigured function type this method can be called without ‘turbofish’.

Return a new instance from read which will stop decoding packet lines when receiving one of the given delimiters.

Modify the peek buffer, overwriting the byte at position with the given byte to replace_with while truncating it to contain only bytes until the newly replaced position.

This is useful if you would want to remove ‘special bytes’ hidden behind, say a NULL byte to disappear and allow standard line readers to read the next line as usual.

Note that position does not include the 4 bytes prefix (they are invisible outside the reader)

Returns the packet line that stopped the iteration, or None if the end wasn’t reached yet, on EOF, or if fail_on_err_lines() was true.

Reset all iteration state allowing to continue a stopped iteration that is not yet at EOF.

This can happen once a delimiter is reached.

Examples found in repository?
src/read/sidebands/blocking_io.rs (line 23)
22
23
24
    fn drop(&mut self) {
        self.parent.reset();
    }
More examples
Hide additional examples
src/read/mod.rs (line 98)
96
97
98
99
100
101
    pub fn replace(&mut self, read: T) -> T {
        let prev = std::mem::replace(&mut self.read, read);
        self.reset();
        self.fail_on_err_lines = false;
        prev
    }

Similar to reset() with support to changing the delimiters.

Examples found in repository?
src/read/sidebands/blocking_io.rs (line 72)
71
72
73
    pub fn reset_with(&mut self, delimiters: &'static [PacketLineRef<'static>]) {
        self.parent.reset_with(delimiters)
    }
More examples
Hide additional examples
src/read/mod.rs (line 77)
75
76
77
78
    pub fn reset(&mut self) {
        let delimiters = std::mem::take(&mut self.delimiters);
        self.reset_with(delimiters);
    }

If value is true the provider will check for special ERR packet lines and stop iteration when one is encountered.

Use [stopped_at()]StreamingPeekableIter::stopped_at() to inspect the cause of the end of the iteration. ne

Replace the reader used with the given read, resetting all other iteration state as well.

Return the inner read

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.