use serde::ser::{Serialize, SerializeStruct, Serializer};
use crate::ast::{Ast, AstImpl};
use crate::errors::ParseErrors;
use crate::symbols::Symbol;
use crate::text::Text;
use crate::tokens::{TokenRepository, TokenRepositoryImpl};
pub struct ParseResult<'s, 't, 'a> {
pub terminals: &'a [Symbol<'s>],
pub variables: &'a [Symbol<'s>],
pub virtuals: &'a [Symbol<'s>],
pub text: Text<'t>,
pub errors: ParseErrors<'s>,
pub tokens: TokenRepositoryImpl,
ast: AstImpl
}
impl<'s, 't, 'a> ParseResult<'s, 't, 'a> {
pub fn new(
terminals: &'a [Symbol<'s>],
variables: &'a [Symbol<'s>],
virtuals: &'a [Symbol<'s>],
text: Text<'t>
) -> ParseResult<'s, 't, 'a> {
ParseResult {
terminals,
variables,
virtuals,
text,
errors: ParseErrors::default(),
tokens: TokenRepositoryImpl::default(),
ast: AstImpl::default()
}
}
pub fn is_success(&self) -> bool {
self.ast.has_root()
}
pub fn get_tokens(&self) -> TokenRepository {
TokenRepository::new(self.terminals, &self.text, &self.tokens)
}
pub fn get_ast<'x>(&'x self) -> Ast<'s, 't, 'x> {
Ast::new(
TokenRepository::new(self.terminals, &self.text, &self.tokens),
self.variables,
self.virtuals,
&self.ast
)
}
pub fn get_parsing_data<'x>(
&'x mut self
) -> (
TokenRepository<'s, 't, 'x>,
&'x mut ParseErrors<'s>,
Ast<'s, 't, 'x>
) {
(
TokenRepository::new_mut(self.terminals, &self.text, &mut self.tokens),
&mut self.errors,
Ast::new_mut(self.variables, self.virtuals, &mut self.ast)
)
}
}
impl<'s, 't, 'a> Serialize for ParseResult<'s, 't, 'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer
{
let ast = self.get_ast();
let root = if self.is_success() {
Some(ast.get_root())
} else {
None
};
let mut state = serializer.serialize_struct("ParseResult", 2)?;
state.serialize_field("errors", &self.errors.errors)?;
state.serialize_field("root", &root)?;
state.end()
}
}