Skip to main content

xiv_emote_parser/log_message/
parser.rs

1use std::borrow::Cow;
2
3use pest_consume::Parser;
4
5pub use super::ast::types::{ConditionState, ConditionText, ConditionTexts, Text};
6use super::{ast::condition::Answers, EmoteTextError};
7
8#[derive(Parser)]
9#[grammar = "log_message/log_message.pest"]
10pub struct LogMessageParser;
11
12pub type EmoteTextResult<T> = std::result::Result<T, EmoteTextError>;
13
14/// The entrypoint to this library. Processes the raw log message, plugging in
15/// data from the [Answers] implementation where appropriate, and produces a plain text result.
16///
17/// A default implementation for [Answers] is provided in [LogMessageAnswers].
18///
19/// [LogMessageAnswers]: super::ast::condition::LogMessageAnswers
20pub fn process_log_message<T>(log_msg: &str, answers: &T) -> EmoteTextResult<String>
21where
22    T: Answers,
23{
24    let condition_texts = extract_condition_texts(log_msg)?;
25
26    Ok(condition_texts
27        .filter_map_texts(answers, |text| match text {
28            Text::Dynamic(d) => Some(answers.as_str(d)),
29            Text::Static(s) => Some(Cow::from(s.to_string())),
30        })
31        .collect())
32}
33
34pub fn extract_condition_texts(log_msg: &str) -> EmoteTextResult<ConditionTexts> {
35    let root = LogMessageParser::parse(Rule::message, log_msg)
36        .map_err(EmoteTextError::ParseError)?
37        .single()
38        .map_err(EmoteTextError::AstError)?;
39    let message = LogMessageParser::message(root).map_err(EmoteTextError::AstError)?;
40    let condition_texts = message.process_string()?;
41    Ok(condition_texts)
42}