fn decode_buf Result)>()

in shed/netstring/src/decode.rs [59:125]


    fn decode_buf<'a>(&mut self, buf: &'a [u8]) -> Result<(usize, Option<(bool, Slice)>)> {
        let mut consumed = 0;
        loop {
            let state = self
                .state
                .take()
                .ok_or(ErrorKind::NetstringDecode("bad state"))?;

            let buf = &buf[consumed..];

            let (next, ret): (State, Option<Option<(bool, Slice)>>) = match state {
                State::Num(mut cur) => {
                    let mut next = None;

                    for (idx, inp) in buf.iter().enumerate() {
                        match *inp {
                            digit @ b'0'..=b'9' => cur = cur * 10 + ((digit - b'0') as usize),
                            b':' => {
                                next = Some((idx + 1, State::Body(cur)));
                                break;
                            }
                            _ => bail!(ErrorKind::NetstringDecode("Bad character in payload size")),
                        }
                    }

                    if let Some((eaten, next)) = next {
                        // We got a complete length, so we can continue without returning
                        // anything.
                        consumed += eaten;
                        (next, None)
                    } else {
                        // Partial input number - consume what we have then return indicating
                        // we need more.
                        consumed += buf.len();

                        (State::Num(cur), Some(None))
                    }
                }

                State::Body(len) => {
                    // length of payload + ','
                    if buf.len() > len {
                        // We have up to the end of the buffer, so we can return it and
                        // start expecting the next buffer.
                        let v = Slice::new(consumed, len);

                        ensure!(buf[len] == b',', ErrorKind::NetstringDecode("missing ','"));
                        consumed += len + 1;

                        (State::Num(0), Some(Some((true, v))))
                    } else {
                        // Consume as much of the input as we can, and leave the state set up
                        // to handle the rest as it arrives.
                        let v = Slice::new(consumed, buf.len());
                        consumed += v.len();

                        (State::Body(len - v.len()), Some(Some((false, v))))
                    }
                }
            };

            self.state = Some(next);
            if let Some(ret) = ret {
                return Ok((consumed, ret));
            }
        }
    }