dg_xch_core 1.0.5

Core library containing type/error definitions, CLVM tools, Consensus and Pool definitions
Documentation
use log::error;

const EOL_CHARS: [u8; 2] = [b'\r', b'\n'];
const QUOTE_CHARS: [u8; 2] = [b'\'', b'"'];
const CONS_CHARS: [u8; 3] = [b'(', b'.', b')'];
const SPACE_CHARS: [u8; 2] = [b' ', b'\t'];
#[derive(Debug)]
pub struct Token<'a> {
    pub bytes: &'a [u8],
    pub index: usize,
}
pub struct Reader<'a> {
    stream: &'a [u8],
    pub index: usize,
}
impl<'a> Reader<'a> {
    pub fn new(stream: &'a [u8]) -> Self {
        Self { stream, index: 0 }
    }
    pub fn consume_whitespace(&mut self) {
        loop {
            while self.index < self.stream.len() && SPACE_CHARS.contains(&self.stream[self.index]) {
                self.index += 1;
            }
            if self.index >= self.stream.len() || self.stream[self.index] != b';' {
                break;
            }
            while self.index < self.stream.len() && EOL_CHARS.contains(&self.stream[self.index]) {
                self.index += 1;
            }
        }
    }
    pub fn consume_until_whitespace(&mut self) {
        while self.index < self.stream.len()
            && !SPACE_CHARS.contains(&self.stream[self.index])
            && self.stream[self.index] != b')'
        {
            self.index += 1;
        }
    }
}
impl<'a> Iterator for Reader<'a> {
    type Item = Token<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        self.consume_whitespace();
        if self.stream.len() <= self.index {
            None
        } else {
            let chr = &self.stream[self.index];
            if CONS_CHARS.contains(chr) {
                let token = Token {
                    bytes: &self.stream[self.index..self.index + 1],
                    index: self.index,
                };
                self.index += 1;
                Some(token)
            } else if QUOTE_CHARS.contains(chr) {
                let start = self.index;
                let mut bs = false;
                self.index += 1;
                loop {
                    if self.stream.len() <= self.index {
                        error!("ERROR: Unterminated String at {}, ", start);
                        return None;
                    } else if bs {
                        bs = false;
                        self.index += 1;
                    } else if self.stream[self.index] == b'\\' {
                        bs = true;
                    } else if self.stream[self.index] == *chr {
                        self.index += 1;
                        return Some(Token {
                            bytes: &self.stream[start..self.index],
                            index: start,
                        });
                    } else {
                        self.index += 1;
                    }
                }
            } else {
                let start = self.index;
                self.consume_until_whitespace();
                Some(Token {
                    bytes: &self.stream[start..self.index],
                    index: start,
                })
            }
        }
    }
}