#![expect(
dead_code,
reason = "解析状态将在同一批次后续 StandardExpressionParser 主链中消费"
)]
use std::sync::Arc;
use thiserror::Error;
use crate::util::Utf16String;
use super::{IStandardExpression, expression_parsing_node::ExpressionParsingNode};
pub(crate) struct ExpressionParsingState {
nodes: Vec<ExpressionParsingNode>,
}
impl ExpressionParsingState {
pub(crate) fn new() -> Self {
Self { nodes: Vec::new() }
}
pub(crate) fn size(&self) -> usize {
self.nodes.len()
}
pub(crate) fn get(
&self,
position: i32,
) -> Result<&ExpressionParsingNode, ExpressionParsingStateError> {
self.nodes
.get(to_index(position)?)
.ok_or(ExpressionParsingStateError::IndexOutOfBounds { position })
}
pub(crate) fn add_node_input(
&mut self,
semi_parsed_string: Option<Utf16String>,
) -> Result<(), ExpressionParsingStateError> {
let input = semi_parsed_string.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "String cannot be null",
})?;
self.nodes.push(ExpressionParsingNode::from_input(input));
Ok(())
}
pub(crate) fn add_node_expression(
&mut self,
parsed_expression: Option<Arc<dyn IStandardExpression>>,
) -> Result<(), ExpressionParsingStateError> {
let expression = parsed_expression.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "Expression cannot be null",
})?;
self.nodes
.push(ExpressionParsingNode::from_expression(expression));
Ok(())
}
pub(crate) fn insert_node_input(
&mut self,
position: i32,
semi_parsed_string: Option<Utf16String>,
) -> Result<(), ExpressionParsingStateError> {
let input = semi_parsed_string.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "String cannot be null",
})?;
let position = insertion_index(position, self.nodes.len())?;
self.nodes
.insert(position, ExpressionParsingNode::from_input(input));
Ok(())
}
pub(crate) fn insert_node_expression(
&mut self,
position: i32,
parsed_expression: Option<Arc<dyn IStandardExpression>>,
) -> Result<(), ExpressionParsingStateError> {
let expression = parsed_expression.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "Expression cannot be null",
})?;
let position = insertion_index(position, self.nodes.len())?;
self.nodes
.insert(position, ExpressionParsingNode::from_expression(expression));
Ok(())
}
pub(crate) fn set_node_input(
&mut self,
position: i32,
semi_parsed_string: Option<Utf16String>,
) -> Result<(), ExpressionParsingStateError> {
let input = semi_parsed_string.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "String cannot be null",
})?;
*self.node_mut(position)? = ExpressionParsingNode::from_input(input);
Ok(())
}
pub(crate) fn set_node_expression(
&mut self,
position: i32,
parsed_expression: Option<Arc<dyn IStandardExpression>>,
) -> Result<(), ExpressionParsingStateError> {
let expression = parsed_expression.ok_or(ExpressionParsingStateError::IllegalArgument {
message: "Expression cannot be null",
})?;
*self.node_mut(position)? = ExpressionParsingNode::from_expression(expression);
Ok(())
}
pub(crate) fn has_string_root(&self) -> bool {
self.has_string_at(0)
}
pub(crate) fn has_expression_root(&self) -> bool {
self.has_expression_at(0)
}
pub(crate) fn has_string_at(&self, position: i32) -> bool {
usize::try_from(position)
.ok()
.and_then(|position| self.nodes.get(position))
.is_some_and(ExpressionParsingNode::is_input)
}
pub(crate) fn has_expression_at(&self, position: i32) -> bool {
usize::try_from(position)
.ok()
.and_then(|position| self.nodes.get(position))
.is_some_and(ExpressionParsingNode::is_expression)
}
fn node_mut(
&mut self,
position: i32,
) -> Result<&mut ExpressionParsingNode, ExpressionParsingStateError> {
self.nodes
.get_mut(to_index(position)?)
.ok_or(ExpressionParsingStateError::IndexOutOfBounds { position })
}
}
#[derive(Debug, Error, Eq, PartialEq)]
pub(crate) enum ExpressionParsingStateError {
#[error("{message}")]
IllegalArgument { message: &'static str },
#[error("Index: {position}")]
IndexOutOfBounds { position: i32 },
}
fn to_index(position: i32) -> Result<usize, ExpressionParsingStateError> {
usize::try_from(position)
.map_err(|_| ExpressionParsingStateError::IndexOutOfBounds { position })
}
fn insertion_index(position: i32, len: usize) -> Result<usize, ExpressionParsingStateError> {
let position = to_index(position)?;
if position > len {
return Err(ExpressionParsingStateError::IndexOutOfBounds {
position: i32::try_from(position).unwrap_or(i32::MAX),
});
}
Ok(position)
}