#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TriviaPiece {
EmptyLine,
LineComment(Box<str>),
BlockComment(bool, Box<[Box<str>]>),
LanguageAnnotation(Box<str>),
}
#[derive(Debug, Clone, Default)]
pub struct Trivia(Option<Box<[TriviaPiece]>>);
impl Trivia {
#[inline]
pub const fn new() -> Self {
Self(None)
}
pub fn one(t: TriviaPiece) -> Self {
Self(Some(Box::new([t])))
}
pub fn push(&mut self, t: TriviaPiece) {
let mut v: Vec<TriviaPiece> = std::mem::take(self).into();
v.push(t);
*self = v.into();
}
pub fn insert(&mut self, idx: usize, t: TriviaPiece) {
let mut v: Vec<TriviaPiece> = std::mem::take(self).into();
v.insert(idx, t);
*self = v.into();
}
pub fn extend<I: IntoIterator<Item = TriviaPiece>>(&mut self, iter: I) {
let mut iter = iter.into_iter();
if let Some(first) = iter.next() {
let mut v: Vec<TriviaPiece> = std::mem::take(self).into();
v.push(first);
v.extend(iter);
*self = v.into();
}
}
#[inline]
pub fn clear(&mut self) {
self.0 = None;
}
}
impl PartialEq for Trivia {
fn eq(&self, other: &Self) -> bool {
self[..] == other[..]
}
}
impl Eq for Trivia {}
impl std::ops::Deref for Trivia {
type Target = [TriviaPiece];
#[inline]
fn deref(&self) -> &Self::Target {
match &self.0 {
Some(v) => v,
None => &[],
}
}
}
impl From<Vec<TriviaPiece>> for Trivia {
fn from(value: Vec<TriviaPiece>) -> Self {
if value.is_empty() {
Self(None)
} else {
Self(Some(value.into_boxed_slice()))
}
}
}
impl From<Trivia> for Vec<TriviaPiece> {
fn from(val: Trivia) -> Self {
val.0.map(Self::from).unwrap_or_default()
}
}
impl IntoIterator for Trivia {
type Item = TriviaPiece;
type IntoIter = std::vec::IntoIter<TriviaPiece>;
fn into_iter(self) -> Self::IntoIter {
Vec::from(self).into_iter()
}
}
impl<'a> IntoIterator for &'a Trivia {
type Item = &'a TriviaPiece;
type IntoIter = std::slice::Iter<'a, TriviaPiece>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TrailingComment(pub Box<str>);
impl From<&TrailingComment> for TriviaPiece {
fn from(tc: &TrailingComment) -> Self {
Self::LineComment(format!(" {}", tc.0).into_boxed_str())
}
}