use pest::iterators::Pair;
use quick_impl::QuickImpl;
use super::RHexLiteral;
use crate::parser::parser::{get_next, map_unique_child, FromPair, Located, Rule};
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct RVariable(pub String);
impl FromPair for RVariable {
fn from_pair(variable: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
assert!(variable.as_rule() == Rule::variable);
Ok(RVariable(variable.as_str().to_owned()))
}
}
impl RVariable {
pub fn as_str(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone)]
pub struct RVariableWithField {
pub variable: Located<RVariable>,
pub field: Located<RVariable>,
}
impl FromPair for RVariableWithField {
fn from_pair(variable_with_field: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
assert!(variable_with_field.as_rule() == Rule::variable_with_field);
let mut inner = variable_with_field.into_inner();
let variable = Located::<RVariable>::from_pair(get_next(&mut inner, Rule::variable))?;
let _ = get_next(&mut inner, Rule::dot);
let field = Located::<RVariable>::from_pair(get_next(&mut inner, Rule::variable))?;
assert!(inner.next() == None);
Ok(Self { variable, field })
}
}
#[derive(Debug, Clone)]
pub struct RCompileVariable(pub Located<RVariable>);
impl FromPair for RCompileVariable {
fn from_pair(compile_variable: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
assert!(compile_variable.as_rule() == Rule::compile_variable);
let mut compile_var_inner = compile_variable.into_inner();
_ = get_next(&mut compile_var_inner, Rule::dol);
let res = Located::<RVariable>::from_pair(get_next(&mut compile_var_inner, Rule::variable))?;
_ = get_next(&mut compile_var_inner, Rule::dol);
Ok(Self(res))
}
}
impl RCompileVariable {
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
#[derive(Debug, Clone, QuickImpl)]
pub enum RHexAlias {
#[quick_impl(impl From)]
HexLiteral(RHexLiteral),
#[quick_impl(impl From)]
Variable(RVariable),
#[quick_impl(impl From)]
CompileVariable(RCompileVariable),
}
impl FromPair for RHexAlias {
fn from_pair(hex_alias: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
assert!(hex_alias.as_rule() == Rule::hex_alias);
map_unique_child(hex_alias, |child| match child.as_rule() {
Rule::hex_literal => Ok(RHexLiteral::from_pair(child)?.into()),
Rule::variable => Ok(RVariable::from_pair(child)?.into()),
Rule::compile_variable => Ok(RCompileVariable::from_pair(child)?.into()),
_ => unreachable!(),
})
}
}
#[derive(Debug, Clone)]
pub struct RConcatenation(pub Vec<Located<RHexAlias>>);
impl FromPair for RConcatenation {
fn from_pair(variables_concat: Pair<Rule>) -> Result<Self, pest::error::Error<Rule>> {
assert!(variables_concat.as_rule() == Rule::concatenation);
let mut variables_concat_inner = variables_concat.into_inner();
let mut res = vec![Located::<RHexAlias>::from_pair(get_next(
&mut variables_concat_inner,
Rule::hex_alias,
))?];
while let Some(at) = variables_concat_inner.next() {
assert!(at.as_rule() == Rule::at);
res.push(Located::<RHexAlias>::from_pair(get_next(
&mut variables_concat_inner,
Rule::hex_alias,
))?)
}
Ok(Self(res))
}
}