use crate::ParserError;
use crate::pest_parser::Rule;
use misty_ast::DataType;
use pest::iterators::Pair;
#[tracing::instrument(skip(pair))]
pub fn parse_data_type(pair: Pair<Rule>) -> Result<DataType, ParserError> {
let data_type_pair = pair
.into_inner()
.next()
.ok_or(ParserError::DataType)
.inspect_err(|error| tracing::debug!(?error, "Failed to parse the DataType"))?;
match data_type_pair.as_rule() {
Rule::primitive => Ok(DataType::Primitive(data_type_pair.as_str().to_string())),
Rule::user_type => Ok(DataType::UserType(data_type_pair.as_str().to_string())),
Rule::container => {
let mut container_inner = data_type_pair.into_inner();
let container_type_name = container_inner
.next()
.ok_or(ParserError::DataTypeContainerName)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the container type name")
})?;
let container_inner_data_type_pair = container_inner
.next()
.ok_or(ParserError::DataTypeContainerInnerType)
.inspect_err(|error| {
tracing::debug!(?error, "Failed to parse the container inner type")
})?;
let inner_data_type = parse_data_type(container_inner_data_type_pair)?;
let container_type = match container_type_name.as_str() {
"vec" => {
DataType::Container(misty_ast::ContainerType::Vec, Box::new(inner_data_type))
}
"option" => {
DataType::Container(misty_ast::ContainerType::Option, Box::new(inner_data_type))
}
_ => unreachable!(),
};
Ok(container_type)
}
_ => unreachable!(),
}
}