cpp_rs 0.1.0

[Not currently ready] A C Preprocessor library and associated binary.
Documentation
use std::borrow::Cow;
use std::iter::Fuse;
use std::ops::RangeInclusive;
use std::str::CharIndices;

pub trait CharSource<'s> {
    fn next(&mut self) -> Option<(usize, char)>;
    fn get_slice(&mut self, range: RangeInclusive<usize>) -> Cow<'s, str>;
    fn get_len(&self) -> usize;
}

pub struct StrSource<'s> {
    input: &'s str,
    char_indices: Fuse<CharIndices<'s>>,
}

impl<'s> CharSource<'s> for StrSource<'s> {
    fn next(&mut self) -> Option<(usize, char)> {
        self.char_indices.next()
    }

    fn get_slice(&mut self, range: RangeInclusive<usize>) -> Cow<'s, str> {
        Cow::Borrowed(self.input.get(range).unwrap())
    }

    fn get_len(&self) -> usize {
        self.input.len()
    }
}

pub struct StringSource {
    input: Vec<(usize, char)>,
    cur_char_idx: usize,
}

impl CharSource<'static> for StringSource {
    fn next(&mut self) -> Option<(usize, char)> {
        if self.cur_char_idx < self.input.len() {
            let out = self.input[self.cur_char_idx];
            self.cur_char_idx += 1;
            Some(out)
        } else {
            None
        }
    }

    fn get_slice(&mut self, range: RangeInclusive<usize>) -> Cow<'static, str> {
        let start_idx = self
            .input
            .binary_search_by_key(range.start(), |x| x.0)
            .unwrap();
        let end_idx = self
            .input
            .binary_search_by_key(range.end(), |x| x.0)
            .unwrap();
        let out: String = self.input[start_idx..=end_idx]
            .iter()
            .map(|x| x.1)
            .collect();

        Cow::Owned(out)
    }

    fn get_len(&self) -> usize {
        self.input.len()
    }
}

impl Into<StringSource> for String {
    fn into(self) -> StringSource {
        StringSource {
            input: self.char_indices().collect(),
            cur_char_idx: 0,
        }
    }
}

impl<'s> Into<StrSource<'s>> for &'s str {
    fn into(self) -> StrSource<'s> {
        StrSource {
            char_indices: self.char_indices().fuse(),
            input: self,
        }
    }
}