use crate::ParserError;
use crate::ast::parse_data_type;
use crate::pest_parser::Rule;
use misty_ast::{DataType, Function};
use pest::iterators::Pair;
#[tracing::instrument(skip(pair))]
pub fn parse_function(pair: Pair<Rule>) -> Result<Function, ParserError> {
let mut function_inner = pair.into_inner();
let name = function_inner
.next()
.ok_or(ParserError::FunctionName)
.inspect_err(|error| tracing::debug!(?error, "Failed to parse the function name"))?
.as_str()
.to_string();
let input_argument_pair = function_inner
.next()
.ok_or(ParserError::FunctionArgument)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the function input argument")
})?;
let input_argument = parse_function_argument(input_argument_pair)?;
let output_argument = function_inner
.next()
.map(|pair| parse_function_argument(pair))
.transpose()?;
Ok(Function {
name,
input: input_argument,
output: output_argument,
})
}
fn parse_function_argument(pair: Pair<Rule>) -> Result<(bool, DataType), ParserError> {
let mut argument_inner = pair.into_inner();
let mut argument_pair = argument_inner
.next()
.ok_or(ParserError::FunctionArgument)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the function argument inner token")
})?;
let is_stream = if argument_pair.as_rule() == Rule::STREAM_KW {
argument_pair = argument_inner
.next()
.ok_or(ParserError::FunctionArgument)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the DataType after the STREAM_KW")
})?;
true
} else {
false
};
let data_type_pair = argument_pair
.into_inner()
.next()
.ok_or(ParserError::FunctionArgumentDataType)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the function argument DataType")
})?;
let data_type = parse_data_type(data_type_pair)?;
Ok((is_stream, data_type))
}