#[derive(Clone, Debug, PartialEq, Eq)] pub enum Token<'a> { Ident(&'a str), Punct(Punct), String(String<'a>), Number(&'a str), } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Punct(pub char, pub Spacing); #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Spacing { Alone, Joint, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct String<'a> { pub pieces: Vec>, pub kind: StringKind, } #[derive(Clone, Debug, PartialEq, Eq)] pub enum StringPiece<'a> { Chars(&'a str), Escape(char), Interp(TokenStream<'a>), } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum StringKind { String, RawString, ScriptString, } #[derive(Clone, Debug, PartialEq, Eq)] pub struct TokenStream<'a>(pub Vec>); impl<'a> peg::Parse for TokenStream<'a> { type PositionRepr = usize; fn start(&self) -> usize { 0 } fn is_eof(&self, pos: usize) -> bool { pos >= self.0.len() } fn position_repr(&self, pos: usize) -> Self::PositionRepr { pos } } impl<'input, 'a: 'input> peg::ParseElem<'input> for TokenStream<'a> { type Element = &'input Token<'a>; fn parse_elem(&'input self, pos: usize) -> peg::RuleResult { use peg::RuleResult; match self.0[pos..].first() { Some(c) => RuleResult::Matched(pos + 1, c), None => RuleResult::Failed, } } }