summaryrefslogtreecommitdiff
path: root/helix-core/src/rope_reader.rs
blob: 20ed7bac1c60351233413b8d6186e13e74be86ae (plain) (blame)
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
use std::io;

use ropey::iter::Chunks;
use ropey::RopeSlice;

pub struct RopeReader<'a> {
    current_chunk: &'a [u8],
    chunks: Chunks<'a>,
}

impl<'a> RopeReader<'a> {
    pub fn new(rope: RopeSlice<'a>) -> RopeReader<'a> {
        RopeReader {
            current_chunk: &[],
            chunks: rope.chunks(),
        }
    }
}

impl io::Read for RopeReader<'_> {
    fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
        let buf_len = buf.len();
        loop {
            let read_bytes = self.current_chunk.read(buf)?;
            buf = &mut buf[read_bytes..];
            if buf.is_empty() {
                return Ok(buf_len);
            }

            if let Some(next_chunk) = self.chunks.next() {
                self.current_chunk = next_chunk.as_bytes();
            } else {
                return Ok(buf_len - buf.len());
            }
        }
    }
}