use erl_tokenize::tokens::{IntegerToken, SymbolToken, VariableToken};
use erl_tokenize::values::Symbol;
use erl_tokenize::{Position, PositionRange};
use super::Type;
use crate::traits::{Parse, TokenRead};
use crate::{Parser, Result};
#[derive(Debug, Clone)]
pub struct ListElement {
pub element_type: Type,
pub non_empty: Option<NonEmpty>,
}
impl Parse for ListElement {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
Ok(ListElement {
element_type: track!(parser.parse())?,
non_empty: track!(parser.parse())?,
})
}
}
impl PositionRange for ListElement {
fn start_position(&self) -> Position {
self.element_type.start_position()
}
fn end_position(&self) -> Position {
self.non_empty
.as_ref()
.map(PositionRange::end_position)
.unwrap_or_else(|| self.element_type.end_position())
}
}
#[derive(Debug, Clone)]
pub struct NonEmpty {
pub _comma: SymbolToken,
pub _triple_dot: SymbolToken,
}
impl Parse for NonEmpty {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
Ok(NonEmpty {
_comma: track!(parser.expect(&Symbol::Comma))?,
_triple_dot: track!(parser.expect(&Symbol::TripleDot))?,
})
}
}
impl PositionRange for NonEmpty {
fn start_position(&self) -> Position {
self._comma.start_position()
}
fn end_position(&self) -> Position {
self._triple_dot.end_position()
}
}
#[derive(Debug, Clone)]
pub struct ByteAndBitSize {
pub byte: ByteSize,
pub _comma: SymbolToken,
pub bit: BitSize,
}
impl Parse for ByteAndBitSize {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
Ok(ByteAndBitSize {
byte: track!(parser.parse())?,
_comma: track!(parser.expect(&Symbol::Comma))?,
bit: track!(parser.parse())?,
})
}
}
impl PositionRange for ByteAndBitSize {
fn start_position(&self) -> Position {
self.byte.start_position()
}
fn end_position(&self) -> Position {
self.bit.end_position()
}
}
#[derive(Debug, Clone)]
pub struct ByteSize {
pub _underscore: VariableToken,
pub _colon: SymbolToken,
pub size: IntegerToken,
}
impl Parse for ByteSize {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
Ok(ByteSize {
_underscore: track!(parser.expect("_"))?,
_colon: track!(parser.expect(&Symbol::Colon))?,
size: track!(parser.parse())?,
})
}
}
impl PositionRange for ByteSize {
fn start_position(&self) -> Position {
self._underscore.start_position()
}
fn end_position(&self) -> Position {
self.size.end_position()
}
}
#[derive(Debug, Clone)]
pub struct BitSize {
pub _underscore0: VariableToken,
pub _colon: SymbolToken,
pub _underscore1: VariableToken,
pub _asterisk: SymbolToken,
pub size: IntegerToken,
}
impl Parse for BitSize {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
Ok(BitSize {
_underscore0: track!(parser.expect("_"))?,
_colon: track!(parser.expect(&Symbol::Colon))?,
_underscore1: track!(parser.expect("_"))?,
_asterisk: track!(parser.expect(&Symbol::Multiply))?,
size: track!(parser.parse())?,
})
}
}
impl PositionRange for BitSize {
fn start_position(&self) -> Position {
self._underscore0.start_position()
}
fn end_position(&self) -> Position {
self.size.end_position()
}
}
#[derive(Debug, Clone)]
#[allow(clippy::large_enum_variant)]
pub enum BitsSpec {
BytesAndBits(ByteAndBitSize),
Bytes(ByteSize),
Bits(BitSize),
}
impl Parse for BitsSpec {
fn parse<T: TokenRead>(parser: &mut Parser<T>) -> Result<Self> {
if let Ok(x) = parser.transaction(Parser::parse) {
Ok(BitsSpec::BytesAndBits(x))
} else if let Ok(x) = parser.transaction(Parser::parse) {
Ok(BitsSpec::Bytes(x))
} else {
Ok(BitsSpec::Bits(track!(parser.parse())?))
}
}
}
impl PositionRange for BitsSpec {
fn start_position(&self) -> Position {
match *self {
BitsSpec::BytesAndBits(ref t) => t.start_position(),
BitsSpec::Bytes(ref t) => t.start_position(),
BitsSpec::Bits(ref t) => t.start_position(),
}
}
fn end_position(&self) -> Position {
match *self {
BitsSpec::BytesAndBits(ref t) => t.end_position(),
BitsSpec::Bytes(ref t) => t.end_position(),
BitsSpec::Bits(ref t) => t.end_position(),
}
}
}