use super::ast::{Span, Spanned};
use rust_decimal::Decimal;
use std::cmp::PartialEq;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Field<'input> {
pub(crate) letters: &'input str,
pub(crate) value: Value<'input>,
pub(crate) raw_value: Vec<&'input str>,
pub(crate) span: Span,
}
impl<'input> Field<'input> {
pub fn iter_bytes(&'input self) -> impl Iterator<Item = &'input u8> {
self.letters
.as_bytes()
.iter()
.chain(self.raw_value.iter().flat_map(|s| s.as_bytes().iter()))
}
}
impl<'input> Spanned for Field<'input> {
fn span(&self) -> Span {
self.span
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Value<'input> {
Rational(Decimal),
Integer(usize),
String(&'input str),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Checksum {
pub(crate) inner: u8,
pub(crate) span: Span,
}
impl Spanned for Checksum {
fn span(&self) -> Span {
self.span
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Newline {
pub(crate) pos: usize,
}
impl Spanned for Newline {
fn span(&self) -> Span {
Span(self.pos, self.pos + 1)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Percent {
pub(crate) pos: usize,
}
impl Spanned for Percent {
fn span(&self) -> Span {
Span(self.pos, self.pos + 1)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Whitespace<'input> {
pub(crate) inner: &'input str,
pub(crate) pos: usize,
}
impl<'input> Whitespace<'input> {
pub fn iter_bytes(&'input self) -> impl Iterator<Item = &'input u8> {
self.inner.as_bytes().iter()
}
}
impl<'input> Spanned for Whitespace<'input> {
fn span(&self) -> Span {
Span(self.pos, self.pos + self.inner.len())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Comment<'input> {
pub(crate) inner: &'input str,
pub(crate) pos: usize,
}
impl<'input> Comment<'input> {
pub fn iter_bytes(&'input self) -> impl Iterator<Item = &'input u8> {
self.inner.as_bytes().iter()
}
}
impl<'input> Spanned for Comment<'input> {
fn span(&self) -> Span {
Span(self.pos, self.pos + self.inner.len())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InlineComment<'input> {
pub(crate) inner: &'input str,
pub(crate) pos: usize,
}
impl<'input> InlineComment<'input> {
pub fn iter_bytes(&'input self) -> impl Iterator<Item = &'input u8> {
self.inner.as_bytes().iter()
}
}
impl<'input> Spanned for InlineComment<'input> {
fn span(&self) -> Span {
Span(self.pos, self.pos + self.inner.len())
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct LineComponent<'input> {
pub(crate) field: Option<Field<'input>>,
pub(crate) whitespace: Option<Whitespace<'input>>,
pub(crate) inline_comment: Option<InlineComment<'input>>,
}
impl<'input> LineComponent<'input> {
pub fn iter_bytes(&'input self) -> impl Iterator<Item = &'input u8> + 'input {
self.field
.iter()
.flat_map(|f| f.iter_bytes())
.chain(self.whitespace.iter().flat_map(|w| w.iter_bytes()))
.chain(self.inline_comment.iter().flat_map(|i| i.iter_bytes()))
}
}