use crate::{
BusinessProcessModelAndNotation,
element::BPMNElement,
semantics::BPMNSubMarking,
sequence_flow::BPMNSequenceFlow,
traits::{objectable::BPMNObject, startable::InitiationMode},
};
use anyhow::{Result, anyhow};
use std::fmt::Debug;
pub trait Processable: BPMNObject + Debug {
fn elements_non_recursive(&self) -> &Vec<BPMNElement>;
fn sequence_flows_non_recursive(&self) -> &Vec<BPMNSequenceFlow>;
fn to_sub_marking(&self, initiation_mode: &InitiationMode) -> Result<BPMNSubMarking>;
fn is_sub_process(&self) -> bool;
fn sequence_flow_index_2_source(&self, sequence_flow_index: usize) -> Result<&BPMNElement> {
let sequence_flow = self
.sequence_flows_non_recursive()
.get(sequence_flow_index)
.ok_or_else(|| anyhow!("sequence flow of index {} not found", sequence_flow_index))?;
self.elements_non_recursive()
.get(sequence_flow.source_local_index)
.ok_or_else(|| {
anyhow!(
"the target of sequence flow `{}` was not found",
sequence_flow.id
)
})
}
fn sequence_flow_index_2_target(&self, sequence_flow_index: usize) -> Result<&BPMNElement> {
let sequence_flow = self
.sequence_flows_non_recursive()
.get(sequence_flow_index)
.ok_or_else(|| anyhow!("sequence flow of index {} not found", sequence_flow_index))?;
self.elements_non_recursive()
.get(sequence_flow.target_local_index)
.ok_or_else(|| {
anyhow!(
"the target of sequence flow `{}` was not found",
sequence_flow.id
)
})
}
}
static EMPTY_FLOWS: Vec<BPMNSequenceFlow> = vec![];
impl Processable for BusinessProcessModelAndNotation {
fn elements_non_recursive(&self) -> &Vec<BPMNElement> {
&self.elements
}
fn sequence_flows_non_recursive(&self) -> &Vec<BPMNSequenceFlow> {
&EMPTY_FLOWS
}
fn to_sub_marking(&self, _initiation_mode: &InitiationMode) -> Result<BPMNSubMarking> {
Err(anyhow!("call the dedicated function"))
}
fn is_sub_process(&self) -> bool {
false
}
}