use crate::connection::information_packet::Content;
use std::any::Any;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct LoopInstruction {
pub jump_to_block_index: Option<usize>,
pub jump_to_node: Option<usize>,
pub context: Option<Arc<dyn Any + Send + Sync>>,
}
#[derive(Debug, Clone)]
pub enum FlowControl {
Continue,
Loop(LoopInstruction),
Branch(Vec<usize>),
Abort,
}
impl FlowControl {
pub fn loop_to_block(index: usize) -> Self {
Self::Loop(LoopInstruction {
jump_to_block_index: Some(index),
jump_to_node: None,
context: None,
})
}
pub fn loop_to_node(node_id: usize) -> Self {
Self::Loop(LoopInstruction {
jump_to_block_index: None,
jump_to_node: Some(node_id),
context: None,
})
}
}
#[derive(Clone, Debug)]
pub enum Output {
Out(Option<Content>),
Err(String),
ErrWithExitCode(Option<i32>, Option<Content>),
ConditionResult(bool),
Flow(FlowControl),
}
impl Output {
pub fn new<H: Send + Sync + 'static>(val: H) -> Self {
Self::Out(Some(Content::new(val)))
}
pub fn empty() -> Self {
Self::Out(None)
}
pub fn error(msg: String) -> Self {
Self::Err(msg)
}
pub fn error_with_exit_code(code: Option<i32>, msg: Option<Content>) -> Self {
Self::ErrWithExitCode(code, msg)
}
pub(crate) fn is_err(&self) -> bool {
match self {
Self::Err(_) | Self::ErrWithExitCode(_, _) => true,
Self::Out(_) | Self::ConditionResult(_) | Self::Flow(_) => false,
}
}
pub fn get_out(&self) -> Option<Content> {
match self {
Self::Out(out) => out.clone(),
Self::Err(_)
| Self::ErrWithExitCode(_, _)
| Self::ConditionResult(_)
| Self::Flow(_) => None,
}
}
pub fn get_err(&self) -> Option<String> {
match self {
Self::Out(_) | Self::ConditionResult(_) | Self::Flow(_) => None,
Self::Err(err) => Some(err.to_string()),
Self::ErrWithExitCode(code, _) => {
let error_code = code.map_or("".to_string(), |v| v.to_string());
Some(format!("code: {error_code}"))
}
}
}
pub(crate) fn conditional_result(&self) -> Option<bool> {
match self {
Self::ConditionResult(b) => Some(*b),
_ => None,
}
}
pub fn get_flow(&self) -> Option<&FlowControl> {
match self {
Self::Flow(flow) => Some(flow),
_ => None,
}
}
pub fn is_empty(&self) -> bool {
matches!(self, Self::Out(None))
}
pub fn has_content(&self) -> bool {
matches!(
self,
Self::Out(Some(_)) | Self::ConditionResult(_) | Self::Flow(_)
)
}
}