use super::{
ebi_command::{EBI_COMMANDS, EbiCommand},
ebi_file_handler::{EBI_FILE_HANDLERS, EbiFileHandler},
};
use crate::{
ebi_file_handlers::{
business_process_model_and_notation::EBI_BUSINESS_PROCESS_MODEL_AND_NOTATION,
compressed_event_log::EBI_COMPRESSED_EVENT_LOG,
deterministic_finite_automaton::EBI_DETERMINISTIC_FINITE_AUTOMATON,
directly_follows_graph::EBI_DIRECTLY_FOLLOWS_GRAPH,
directly_follows_model::EBI_DIRECTLY_FOLLOWS_MODEL, event_log_csv::EBI_EVENT_LOG_CSV,
event_log_ocel::EBI_EVENT_LOG_OCEL, event_log_python::EBI_EVENT_LOG_PYTHON,
executions::EBI_EXECUTIONS, finite_language::EBI_FINITE_LANGUAGE,
finite_stochastic_language::EBI_FINITE_STOCHASTIC_LANGUAGE,
finite_stochastic_partially_ordered_language::EBI_FINITE_STOCHASTIC_PARTIALLY_ORDERED_LANGUAGE,
labelled_petri_net::EBI_LABELLED_PETRI_NET,
language_of_alignments::EBI_LANGUAGE_OF_ALIGNMENTS,
partially_ordered_workflow_language::EBI_PARTIALLY_ORDERED_WORKFLOW_LANGUAGE,
portable_document_format::EBI_PORTABLE_DOCUMENT_FORMAT,
portable_network_graphics::EBI_PORTABLE_NETWORK_GRAPHCIS, process_tree::EBI_PROCESS_TREE,
scalable_vector_graphics::EBI_SCALABLE_VECTOR_GRAPHICS,
stochastic_deterministic_finite_automaton::EBI_STOCHASTIC_DETERMINISTIC_FINITE_AUTOMATON,
stochastic_directly_follows_model::EBI_STOCHASTIC_DIRECTLY_FOLLOWS_MODEL,
stochastic_labelled_petri_net::EBI_STOCHASTIC_LABELLED_PETRI_NET,
stochastic_language_of_alignments::EBI_STOCHASTIC_LANGUAGE_OF_ALIGNMENTS,
stochastic_nondeterministic_finite_automaton::EBI_STOCHASTIC_NONDETERMINISTIC_FINITE_AUTOMATON,
stochastic_process_tree::EBI_STOCHASTIC_PROCESS_TREE,
},
math::{log_div::LogDiv, root::ContainsRoot, root_log_div::RootLogDiv},
prom::java_object_handler::{
JAVA_OBJECT_HANDLERS_BOOL, JAVA_OBJECT_HANDLERS_CONTAINSROOT,
JAVA_OBJECT_HANDLERS_FRACTION, JAVA_OBJECT_HANDLERS_LOGDIV,
JAVA_OBJECT_HANDLERS_LOGPOLYNOMIAL, JAVA_OBJECT_HANDLERS_ROOTLOGDIV,
JAVA_OBJECT_HANDLERS_STRING, JAVA_OBJECT_HANDLERS_USIZE, JavaObjectHandler,
},
};
use ebi_objects::{
BusinessProcessModelAndNotation, CompressedEventLogXes, EbiObject, EbiObjectType,
EventLogPython, Exportable, FiniteStochasticPartiallyOrderedLanguage, PortableDocumentFormat,
PortableNetworkGraphics, StochasticBusinessProcessModelAndNotation,
StochasticNondeterministicFiniteAutomaton,
anyhow::{Context, Result, anyhow},
ebi_arithmetic::{Exporter, Fraction},
ebi_objects::{
compressed_event_log::CompressedEventLog,
compressed_event_log_event_attributes::CompressedEventLogEventAttributes,
compressed_event_log_trace_attributes::CompressedEventLogTraceAttributes,
deterministic_finite_automaton::DeterministicFiniteAutomaton,
directly_follows_graph::DirectlyFollowsGraph, directly_follows_model::DirectlyFollowsModel,
event_log_csv::EventLogCsv, event_log_ocel::EventLogOcel, executions::Executions,
finite_language::FiniteLanguage, finite_stochastic_language::FiniteStochasticLanguage,
labelled_petri_net::LabelledPetriNet, language_of_alignments::LanguageOfAlignments,
partially_ordered_workflow_language::PartiallyOrderedWorkflowLanguage,
process_tree::ProcessTree, scalable_vector_graphics::ScalableVectorGraphics,
stochastic_deterministic_finite_automaton::StochasticDeterministicFiniteAutomaton,
stochastic_directly_follows_model::StochasticDirectlyFollowsModel,
stochastic_labelled_petri_net::StochasticLabelledPetriNet,
stochastic_language_of_alignments::StochasticLanguageOfAlignments,
stochastic_process_tree::StochasticProcessTree,
},
};
use ebi_optimisation::ebi_arithmetic::log_polynomial::log_polynomial::LogPolynomial;
use std::{
collections::BTreeSet,
fmt::{self, Debug, Display},
fs::File,
io::Write,
path::PathBuf,
};
use strum_macros::{Display, EnumIs, EnumIter, IntoStaticStr};
#[derive(Display, Clone)]
pub enum EbiOutput {
Object(EbiObject),
String(String),
Usize(usize),
Fraction(Fraction),
LogDiv(LogDiv),
LogPolynomial(LogPolynomial),
ContainsRoot(ContainsRoot),
RootLogDiv(RootLogDiv),
Bool(bool),
}
impl EbiOutput {
pub fn get_type(&self) -> EbiOutputType {
match self {
EbiOutput::Object(o) => EbiOutputType::ObjectType(o.get_type()),
EbiOutput::String(_) => EbiOutputType::String,
EbiOutput::Usize(_) => EbiOutputType::Usize,
EbiOutput::Fraction(_) => EbiOutputType::Fraction,
EbiOutput::LogDiv(_) => EbiOutputType::LogDiv,
EbiOutput::LogPolynomial(_) => EbiOutputType::LogPolynomial,
EbiOutput::ContainsRoot(_) => EbiOutputType::ContainsRoot,
EbiOutput::RootLogDiv(_) => EbiOutputType::RootLogDiv,
EbiOutput::Bool(_) => EbiOutputType::Bool,
}
}
}
#[cfg(any(test, feature = "testactivities"))]
impl ebi_objects::ebi_activity_key::has_activity_key::TestActivityKey for EbiOutput {
fn test_activity_key(&self) {
match self {
EbiOutput::Object(ebi_object) => ebi_object.test_activity_key(),
EbiOutput::String(_)
| EbiOutput::Usize(_)
| EbiOutput::Fraction(_)
| EbiOutput::LogDiv(_)
| EbiOutput::LogPolynomial(_)
| EbiOutput::ContainsRoot(_)
| EbiOutput::RootLogDiv(_)
| EbiOutput::Bool(_) => {}
}
}
}
#[derive(PartialEq, Eq, EnumIter, Hash, Clone, Debug)]
pub enum EbiOutputType {
ObjectType(EbiObjectType),
String,
Usize,
Fraction,
LogDiv,
LogPolynomial,
ContainsRoot,
RootLogDiv,
Bool,
}
impl EbiOutputType {
pub fn get_applicable_commands(&self) -> BTreeSet<Vec<&'static EbiCommand>> {
let mut result = EBI_COMMANDS.get_command_paths();
result.retain(|path| {
if let EbiCommand::Command {
output_type: output,
..
} = path[path.len() - 1]
{
if output == &self {
return true;
}
}
false
});
result
}
pub fn get_exporters(&self) -> Vec<EbiExporter> {
let mut result = BTreeSet::new();
match self {
EbiOutputType::ObjectType(etype) => {
for file_handler in EBI_FILE_HANDLERS {
for exporter in file_handler.object_exporters {
if &exporter.get_type() == etype {
result.insert(EbiExporter::Object(exporter, file_handler));
}
}
for exporter in file_handler.object_exporters_fallible {
if &exporter.get_type() == etype {
result.insert(EbiExporter::Object(exporter, file_handler));
}
}
}
result.into_iter().collect()
}
EbiOutputType::String => vec![EbiExporter::String],
EbiOutputType::Usize => vec![EbiExporter::Usize],
EbiOutputType::Fraction => vec![EbiExporter::Fraction],
EbiOutputType::LogDiv => vec![EbiExporter::LogDiv],
EbiOutputType::LogPolynomial => vec![EbiExporter::LogPolynomial],
EbiOutputType::ContainsRoot => vec![EbiExporter::ContainsRoot],
EbiOutputType::RootLogDiv => vec![EbiExporter::RootLogDiv],
EbiOutputType::Bool => vec![EbiExporter::Bool],
}
}
pub fn get_default_exporter(&self) -> EbiExporter {
match self {
EbiOutputType::ObjectType(EbiObjectType::BusinessProcessModelAndNotation) => {
EbiExporter::Object(
&EbiObjectExporter::BusinessProcessModelAndNotation(
BusinessProcessModelAndNotation::export_from_object,
),
&EBI_BUSINESS_PROCESS_MODEL_AND_NOTATION,
)
}
EbiOutputType::ObjectType(EbiObjectType::StochasticBusinessProcessModelAndNotation) => {
EbiExporter::Object(
&EbiObjectExporter::StochasticBusinessProcessModelAndNotation(
StochasticBusinessProcessModelAndNotation::export_from_object,
),
&EBI_BUSINESS_PROCESS_MODEL_AND_NOTATION,
)
}
EbiOutputType::ObjectType(EbiObjectType::LanguageOfAlignments) => EbiExporter::Object(
&EbiObjectExporter::LanguageOfAlignments(LanguageOfAlignments::export_from_object),
&EBI_LANGUAGE_OF_ALIGNMENTS,
),
EbiOutputType::ObjectType(EbiObjectType::StochasticLanguageOfAlignments) => {
EbiExporter::Object(
&EbiObjectExporter::StochasticLanguageOfAlignments(
StochasticLanguageOfAlignments::export_from_object,
),
&EBI_STOCHASTIC_LANGUAGE_OF_ALIGNMENTS,
)
}
EbiOutputType::ObjectType(EbiObjectType::DeterministicFiniteAutomaton) => {
EbiExporter::Object(
&EbiObjectExporter::DeterministicFiniteAutomaton(
DeterministicFiniteAutomaton::export_from_object,
),
&EBI_DETERMINISTIC_FINITE_AUTOMATON,
)
}
EbiOutputType::ObjectType(EbiObjectType::DirectlyFollowsGraph) => EbiExporter::Object(
&EbiObjectExporter::DirectlyFollowsGraph(DirectlyFollowsGraph::export_from_object),
&EBI_DIRECTLY_FOLLOWS_GRAPH,
),
EbiOutputType::ObjectType(EbiObjectType::DirectlyFollowsModel) => EbiExporter::Object(
&EbiObjectExporter::DirectlyFollowsModel(DirectlyFollowsModel::export_from_object),
&EBI_DIRECTLY_FOLLOWS_MODEL,
),
EbiOutputType::ObjectType(EbiObjectType::StochasticDirectlyFollowsModel) => {
EbiExporter::Object(
&EbiObjectExporter::StochasticDirectlyFollowsModel(
StochasticDirectlyFollowsModel::export_from_object,
),
&EBI_STOCHASTIC_DIRECTLY_FOLLOWS_MODEL,
)
}
EbiOutputType::ObjectType(EbiObjectType::EventLog) => EbiExporter::Object(
&EbiObjectExporter::EventLog(CompressedEventLog::export_from_object),
&EBI_COMPRESSED_EVENT_LOG,
),
EbiOutputType::ObjectType(EbiObjectType::EventLogCsv) => EbiExporter::Object(
&EbiObjectExporter::EventLog(EventLogCsv::export_from_object),
&EBI_EVENT_LOG_CSV,
),
EbiOutputType::ObjectType(EbiObjectType::EventLogOcel) => EbiExporter::Object(
&EbiObjectExporter::EventLog(EventLogOcel::export_from_object),
&EBI_EVENT_LOG_OCEL,
),
EbiOutputType::ObjectType(EbiObjectType::EventLogPython) => EbiExporter::Object(
&EbiObjectExporter::EventLogPython(EventLogPython::export_from_object),
&EBI_EVENT_LOG_PYTHON,
),
EbiOutputType::ObjectType(EbiObjectType::EventLogTraceAttributes) => {
EbiExporter::Object(
&EbiObjectExporter::EventLog(
CompressedEventLogTraceAttributes::export_from_object,
),
&EBI_COMPRESSED_EVENT_LOG,
)
}
EbiOutputType::ObjectType(EbiObjectType::EventLogEventAttributes) => {
EbiExporter::Object(
&EbiObjectExporter::EventLogEventAttributes(
CompressedEventLogEventAttributes::export_from_object,
),
&EBI_COMPRESSED_EVENT_LOG,
)
}
EbiOutputType::ObjectType(EbiObjectType::EventLogXes) => EbiExporter::Object(
&EbiObjectExporter::EventLog(CompressedEventLogXes::export_from_object),
&EBI_COMPRESSED_EVENT_LOG,
),
EbiOutputType::ObjectType(EbiObjectType::Executions) => EbiExporter::Object(
&EbiObjectExporter::Executions(Executions::export_from_object),
&EBI_EXECUTIONS,
),
EbiOutputType::ObjectType(EbiObjectType::FiniteLanguage) => EbiExporter::Object(
&EbiObjectExporter::FiniteLanguage(FiniteLanguage::export_from_object),
&EBI_FINITE_LANGUAGE,
),
EbiOutputType::ObjectType(EbiObjectType::FiniteStochasticLanguage) => {
EbiExporter::Object(
&EbiObjectExporter::FiniteStochasticLanguage(
FiniteStochasticLanguage::export_from_object,
),
&EBI_FINITE_STOCHASTIC_LANGUAGE,
)
}
EbiOutputType::ObjectType(EbiObjectType::FiniteStochasticPartiallyOrderedLanguage) => {
EbiExporter::Object(
&&EbiObjectExporter::FiniteStochasticPartiallyOrderedLanguage(
FiniteStochasticPartiallyOrderedLanguage::export_from_object,
),
&EBI_FINITE_STOCHASTIC_PARTIALLY_ORDERED_LANGUAGE,
)
}
EbiOutputType::ObjectType(EbiObjectType::LabelledPetriNet) => EbiExporter::Object(
&EbiObjectExporter::LabelledPetriNet(LabelledPetriNet::export_from_object),
&EBI_LABELLED_PETRI_NET,
),
EbiOutputType::ObjectType(EbiObjectType::StochasticDeterministicFiniteAutomaton) => {
EbiExporter::Object(
&&EbiObjectExporter::StochasticDeterministicFiniteAutomaton(
StochasticDeterministicFiniteAutomaton::export_from_object,
),
&EBI_STOCHASTIC_DETERMINISTIC_FINITE_AUTOMATON,
)
}
EbiOutputType::ObjectType(EbiObjectType::StochasticNondeterministicFiniteAutomaton) => {
EbiExporter::Object(
&&EbiObjectExporter::StochasticNondeterministicFiniteAutomaton(
StochasticNondeterministicFiniteAutomaton::export_from_object,
),
&EBI_STOCHASTIC_NONDETERMINISTIC_FINITE_AUTOMATON,
)
}
EbiOutputType::ObjectType(EbiObjectType::StochasticLabelledPetriNet) => {
EbiExporter::Object(
&&EbiObjectExporter::StochasticLabelledPetriNet(
StochasticLabelledPetriNet::export_from_object,
),
&EBI_STOCHASTIC_LABELLED_PETRI_NET,
)
}
EbiOutputType::ObjectType(EbiObjectType::ProcessTree) => EbiExporter::Object(
&&EbiObjectExporter::ProcessTree(ProcessTree::export_from_object),
&EBI_PROCESS_TREE,
),
EbiOutputType::ObjectType(EbiObjectType::StochasticProcessTree) => EbiExporter::Object(
&&EbiObjectExporter::StochasticProcessTree(
StochasticProcessTree::export_from_object,
),
&EBI_STOCHASTIC_PROCESS_TREE,
),
EbiOutputType::ObjectType(EbiObjectType::PartiallyOrderedWorkflowLanguage) => {
EbiExporter::Object(
&&EbiObjectExporter::PartiallyOrderedWorkflowLanguage(
PartiallyOrderedWorkflowLanguage::export_from_object,
),
&EBI_PARTIALLY_ORDERED_WORKFLOW_LANGUAGE,
)
}
EbiOutputType::ObjectType(EbiObjectType::ScalableVectorGraphics) => {
EbiExporter::Object(
&EbiObjectExporter::ScalableVectorGraphics(
ScalableVectorGraphics::export_from_object,
),
&EBI_SCALABLE_VECTOR_GRAPHICS,
)
}
EbiOutputType::ObjectType(EbiObjectType::PortableDocumentFormat) => {
EbiExporter::Object(
&EbiObjectExporter::PortableDocumentFormat(
PortableDocumentFormat::export_from_object,
),
&EBI_PORTABLE_DOCUMENT_FORMAT,
)
}
EbiOutputType::ObjectType(EbiObjectType::PortableNetworkGraphics) => {
EbiExporter::Object(
&EbiObjectExporter::PortableNetworkGraphics(
PortableNetworkGraphics::export_from_object,
),
&EBI_PORTABLE_NETWORK_GRAPHCIS,
)
}
EbiOutputType::String => EbiExporter::String,
EbiOutputType::Usize => EbiExporter::Usize,
EbiOutputType::Fraction => EbiExporter::Fraction,
EbiOutputType::LogDiv => EbiExporter::LogDiv,
EbiOutputType::LogPolynomial => EbiExporter::LogPolynomial,
EbiOutputType::ContainsRoot => EbiExporter::ContainsRoot,
EbiOutputType::RootLogDiv => EbiExporter::RootLogDiv,
EbiOutputType::Bool => EbiExporter::Bool,
}
}
}
impl Display for EbiOutputType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EbiOutputType::ObjectType(t) => Display::fmt(t, f),
EbiOutputType::String => Display::fmt(&"text", f),
EbiOutputType::Usize => Display::fmt(&"integer", f),
EbiOutputType::Fraction => Display::fmt(&"fraction", f),
EbiOutputType::LogDiv => Display::fmt(&"logarithm", f),
EbiOutputType::LogPolynomial => Display::fmt(&"logarithm", f),
EbiOutputType::ContainsRoot => Display::fmt(&"root", f),
EbiOutputType::RootLogDiv => Display::fmt(&"rootlog", f),
EbiOutputType::Bool => Display::fmt(&"bool", f),
}
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum EbiExporter {
Object(&'static EbiObjectExporter, &'static EbiFileHandler),
String,
Usize,
Fraction,
LogDiv,
LogPolynomial,
ContainsRoot,
RootLogDiv,
Bool,
}
impl EbiExporter {
pub fn export_from_object(&self, output: EbiOutput, f: &mut dyn std::io::Write) -> Result<()> {
match (self, output) {
(EbiExporter::Object(exporter, _), object) => exporter.export(object, f),
(EbiExporter::String, EbiOutput::String(object)) => object.export(f),
(EbiExporter::String, _) => {
return Err(anyhow!("Cannot export {} as string", self.get_name()));
}
(EbiExporter::Usize, EbiOutput::Usize(object)) => object.export(f),
(EbiExporter::Usize, _) => {
return Err(anyhow!("Cannot export {} as number", self.get_name()));
}
(EbiExporter::Fraction, EbiOutput::Fraction(object)) => object.export(f),
(EbiExporter::Fraction, _) => {
return Err(anyhow!("Cannot export {} as fraction", self.get_name()));
}
(EbiExporter::LogDiv, EbiOutput::LogDiv(object)) => object.export(f),
(EbiExporter::LogDiv, _) => {
return Err(anyhow!("Cannot export {} as logdiv", self.get_name()));
}
(EbiExporter::LogPolynomial, EbiOutput::LogPolynomial(object)) => object.export(f),
(EbiExporter::LogPolynomial, _) => {
return Err(anyhow!(
"Cannot export {} as log polynomial",
self.get_name()
));
}
(EbiExporter::ContainsRoot, EbiOutput::ContainsRoot(object)) => object.export(f),
(EbiExporter::ContainsRoot, _) => {
return Err(anyhow!("Cannot export {} as containsroot", self.get_name()));
}
(EbiExporter::RootLogDiv, EbiOutput::RootLogDiv(object)) => object.export(f),
(EbiExporter::RootLogDiv, _) => {
return Err(anyhow!("Cannot export {} as rootlogdiv", self.get_name()));
}
(EbiExporter::Bool, EbiOutput::Bool(object)) => object.export(f),
(EbiExporter::Bool, _) => {
return Err(anyhow!("Cannot export {} as bool", self.get_name()));
}
}
}
pub fn get_article(&self) -> &str {
match self {
EbiExporter::Object(_, file_handler) => file_handler.article,
EbiExporter::String => "",
EbiExporter::Usize => "an",
EbiExporter::Fraction => "a",
EbiExporter::LogDiv => "a",
EbiExporter::LogPolynomial => "a",
EbiExporter::ContainsRoot => "a",
EbiExporter::RootLogDiv => "a",
EbiExporter::Bool => "a",
}
}
pub fn get_name(&self) -> &str {
match self {
EbiExporter::Object(_, file_handler) => file_handler.name,
EbiExporter::String => "string",
EbiExporter::Usize => "integer",
EbiExporter::Fraction => "fraction",
EbiExporter::LogDiv => "logdiv",
EbiExporter::LogPolynomial => "logpolynomial",
EbiExporter::ContainsRoot => "containsroot",
EbiExporter::RootLogDiv => "rootlogdiv",
EbiExporter::Bool => "boolean",
}
}
pub fn get_java_object_handlers(&self) -> &'static [JavaObjectHandler] {
match self {
EbiExporter::Object(_, file_handler) => file_handler.java_object_handlers,
EbiExporter::String => JAVA_OBJECT_HANDLERS_STRING,
EbiExporter::Usize => JAVA_OBJECT_HANDLERS_USIZE,
EbiExporter::Fraction => JAVA_OBJECT_HANDLERS_FRACTION,
EbiExporter::LogDiv => JAVA_OBJECT_HANDLERS_LOGDIV,
EbiExporter::LogPolynomial => JAVA_OBJECT_HANDLERS_LOGPOLYNOMIAL,
EbiExporter::ContainsRoot => JAVA_OBJECT_HANDLERS_CONTAINSROOT,
EbiExporter::RootLogDiv => JAVA_OBJECT_HANDLERS_ROOTLOGDIV,
EbiExporter::Bool => JAVA_OBJECT_HANDLERS_BOOL,
}
}
pub fn get_extension(&self) -> &str {
match self {
EbiExporter::Object(_, file_handler) => file_handler.file_extension,
EbiExporter::String => "txt",
EbiExporter::Usize => "int",
EbiExporter::Fraction => "frac",
EbiExporter::LogDiv => "logdiv",
EbiExporter::LogPolynomial => "logpol",
EbiExporter::ContainsRoot => "croot",
EbiExporter::RootLogDiv => "rldiv",
EbiExporter::Bool => "bool",
}
}
pub fn is_binary(&self) -> bool {
match self {
EbiExporter::Object(_, file_handler) => file_handler.is_binary,
EbiExporter::String => false,
EbiExporter::Usize => false,
EbiExporter::Fraction => false,
EbiExporter::LogDiv => false,
EbiExporter::LogPolynomial => false,
EbiExporter::ContainsRoot => false,
EbiExporter::RootLogDiv => false,
EbiExporter::Bool => false,
}
}
}
impl Display for EbiExporter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EbiExporter::Object(_, file_handler) => Display::fmt(file_handler, f),
EbiExporter::String => Display::fmt(&"text", f),
EbiExporter::Usize => Display::fmt(&"integer", f),
EbiExporter::Fraction => Display::fmt(&"fraction", f),
EbiExporter::LogDiv => Display::fmt(&"logarithm", f),
EbiExporter::LogPolynomial => Display::fmt(&"logarithm", f),
EbiExporter::ContainsRoot => Display::fmt(&"root", f),
EbiExporter::RootLogDiv => Display::fmt(&"rootlog", f),
EbiExporter::Bool => Display::fmt(&"boolean", f),
}
}
}
#[derive(Hash, IntoStaticStr, Eq, EnumIs)]
pub enum EbiObjectExporter {
BusinessProcessModelAndNotation(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLog(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogCsv(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogEventAttributes(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogOcel(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogTraceAttributes(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogXes(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
EventLogPython(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
DirectlyFollowsModel(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
StochasticDirectlyFollowsModel(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
FiniteLanguage(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
FiniteStochasticLanguage(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
FiniteStochasticPartiallyOrderedLanguage(
fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>,
),
LabelledPetriNet(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
StochasticBusinessProcessModelAndNotation(
fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>,
),
StochasticDeterministicFiniteAutomaton(
fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>,
),
StochasticNondeterministicFiniteAutomaton(
fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>,
),
StochasticLabelledPetriNet(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
LanguageOfAlignments(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
StochasticLanguageOfAlignments(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
DeterministicFiniteAutomaton(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
ProcessTree(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
StochasticProcessTree(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
PartiallyOrderedWorkflowLanguage(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
Executions(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
DirectlyFollowsGraph(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
ScalableVectorGraphics(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
PortableDocumentFormat(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
PortableNetworkGraphics(fn(object: EbiObject, &mut dyn std::io::Write) -> Result<()>),
}
impl EbiObjectExporter {
pub fn get_type(&self) -> EbiObjectType {
match self {
EbiObjectExporter::BusinessProcessModelAndNotation(_) => {
EbiObjectType::BusinessProcessModelAndNotation
}
EbiObjectExporter::EventLog(_) => EbiObjectType::EventLog,
EbiObjectExporter::EventLogCsv(_) => EbiObjectType::EventLogCsv,
EbiObjectExporter::EventLogEventAttributes(_) => EbiObjectType::EventLogEventAttributes,
EbiObjectExporter::EventLogOcel(_) => EbiObjectType::EventLogOcel,
EbiObjectExporter::EventLogPython(_) => EbiObjectType::EventLogPython,
EbiObjectExporter::EventLogTraceAttributes(_) => EbiObjectType::EventLogTraceAttributes,
EbiObjectExporter::EventLogXes(_) => EbiObjectType::EventLogXes,
EbiObjectExporter::DirectlyFollowsModel(_) => EbiObjectType::DirectlyFollowsModel,
EbiObjectExporter::StochasticBusinessProcessModelAndNotation(_) => {
EbiObjectType::StochasticBusinessProcessModelAndNotation
}
EbiObjectExporter::StochasticDirectlyFollowsModel(_) => {
EbiObjectType::StochasticDirectlyFollowsModel
}
EbiObjectExporter::FiniteLanguage(_) => EbiObjectType::FiniteLanguage,
EbiObjectExporter::FiniteStochasticLanguage(_) => {
EbiObjectType::FiniteStochasticLanguage
}
EbiObjectExporter::FiniteStochasticPartiallyOrderedLanguage(_) => {
EbiObjectType::FiniteStochasticPartiallyOrderedLanguage
}
EbiObjectExporter::LabelledPetriNet(_) => EbiObjectType::LabelledPetriNet,
EbiObjectExporter::StochasticDeterministicFiniteAutomaton(_) => {
EbiObjectType::StochasticDeterministicFiniteAutomaton
}
EbiObjectExporter::StochasticNondeterministicFiniteAutomaton(_) => {
EbiObjectType::StochasticNondeterministicFiniteAutomaton
}
EbiObjectExporter::StochasticLabelledPetriNet(_) => {
EbiObjectType::StochasticLabelledPetriNet
}
EbiObjectExporter::LanguageOfAlignments(_) => EbiObjectType::LanguageOfAlignments,
EbiObjectExporter::StochasticLanguageOfAlignments(_) => {
EbiObjectType::StochasticLanguageOfAlignments
}
EbiObjectExporter::DeterministicFiniteAutomaton(_) => {
EbiObjectType::DeterministicFiniteAutomaton
}
EbiObjectExporter::ProcessTree(_) => EbiObjectType::ProcessTree,
EbiObjectExporter::StochasticProcessTree(_) => EbiObjectType::StochasticProcessTree,
EbiObjectExporter::PartiallyOrderedWorkflowLanguage(_) => {
EbiObjectType::PartiallyOrderedWorkflowLanguage
}
EbiObjectExporter::Executions(_) => EbiObjectType::Executions,
EbiObjectExporter::DirectlyFollowsGraph(_) => EbiObjectType::DirectlyFollowsGraph,
EbiObjectExporter::ScalableVectorGraphics(_) => EbiObjectType::ScalableVectorGraphics,
EbiObjectExporter::PortableDocumentFormat(_) => EbiObjectType::PortableDocumentFormat,
EbiObjectExporter::PortableNetworkGraphics(_) => EbiObjectType::PortableNetworkGraphics,
}
}
pub fn export(&self, object: EbiOutput, f: &mut dyn std::io::Write) -> Result<()> {
if let EbiOutput::Object(object) = object {
match self {
EbiObjectExporter::BusinessProcessModelAndNotation(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::EventLog(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogCsv(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogEventAttributes(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogOcel(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogPython(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogTraceAttributes(exporter) => (exporter)(object, f),
EbiObjectExporter::EventLogXes(exporter) => (exporter)(object, f),
EbiObjectExporter::DirectlyFollowsModel(exporter) => (exporter)(object, f),
EbiObjectExporter::StochasticBusinessProcessModelAndNotation(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::StochasticDirectlyFollowsModel(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::FiniteLanguage(exporter) => (exporter)(object, f),
EbiObjectExporter::FiniteStochasticLanguage(exporter) => (exporter)(object, f),
EbiObjectExporter::FiniteStochasticPartiallyOrderedLanguage(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::LabelledPetriNet(exporter) => (exporter)(object, f),
EbiObjectExporter::StochasticDeterministicFiniteAutomaton(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::StochasticNondeterministicFiniteAutomaton(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::StochasticLabelledPetriNet(exporter) => (exporter)(object, f),
EbiObjectExporter::LanguageOfAlignments(exporter) => (exporter)(object, f),
EbiObjectExporter::StochasticLanguageOfAlignments(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::DeterministicFiniteAutomaton(exporter) => (exporter)(object, f),
EbiObjectExporter::ProcessTree(exporter) => (exporter)(object, f),
EbiObjectExporter::StochasticProcessTree(exporter) => (exporter)(object, f),
EbiObjectExporter::PartiallyOrderedWorkflowLanguage(exporter) => {
(exporter)(object, f)
}
EbiObjectExporter::Executions(exporter) => (exporter)(object, f),
EbiObjectExporter::DirectlyFollowsGraph(exporter) => (exporter)(object, f),
EbiObjectExporter::ScalableVectorGraphics(exporter) => (exporter)(object, f),
EbiObjectExporter::PortableDocumentFormat(exporter) => (exporter)(object, f),
EbiObjectExporter::PortableNetworkGraphics(exporter) => (exporter)(object, f),
}
} else {
Err(anyhow!("cannot export non-object as object"))
}
}
}
impl Display for EbiObjectExporter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let right: &'static str = self.into();
write!(f, "{}", right)
}
}
impl Debug for EbiObjectExporter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let right: &'static str = self.into();
write!(f, "{}", right)
}
}
impl PartialEq for EbiObjectExporter {
fn eq(&self, other: &Self) -> bool {
self.get_type() == other.get_type()
}
}
impl PartialOrd for EbiObjectExporter {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.get_type().partial_cmp(&other.get_type())
}
}
impl Ord for EbiObjectExporter {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.get_type().cmp(&other.get_type())
}
}
pub fn export_object(to_file: &PathBuf, object: EbiOutput, exporter: EbiExporter) -> Result<()> {
let file =
File::create(to_file).with_context(|| format!("Writing result to file {:?}.", to_file))?;
let mut writer = std::io::BufWriter::new(&file);
exporter
.export_from_object(object, &mut writer)
.with_context(|| format!("Writing result to file {:?}.", to_file))?;
return writer
.flush()
.with_context(|| format!("writing result to file {:?}", to_file));
}
pub fn export_to_string(object: EbiOutput, exporter: &EbiExporter) -> Result<String> {
let mut f = vec![];
exporter.export_from_object(object, &mut f)?;
Ok(String::from_utf8(f)?)
}
pub fn export_to_bytes(object: EbiOutput, exporter: &EbiExporter) -> Result<Vec<u8>> {
let mut f = vec![];
exporter.export_from_object(object, &mut f)?;
Ok(f)
}
#[cfg(test)]
mod tests {
use super::{EbiExporter, EbiOutputType, export_to_bytes, export_to_string};
use crate::{
ebi_framework::{
ebi_command::EbiCommand, ebi_file_handler::EBI_FILE_HANDLERS, ebi_input::EbiInput,
ebi_output::EbiOutput,
},
math::{
log_div::LogDiv,
root::{ContainsRoot, Root},
root_log_div::RootLogDiv,
},
tests::tests::get_all_test_files_for_file,
};
use ebi_objects::ebi_arithmetic::{Fraction, One, Zero};
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use std::{fs, io::Cursor, path::PathBuf};
use strum::IntoEnumIterator;
#[test]
fn all_exporters() {
let files = fs::read_dir("./testfiles").unwrap();
let files = files.into_iter().map(|d| d.unwrap()).collect::<Vec<_>>();
files.into_par_iter().for_each(|file| {
for (object, importer, _, f) in get_all_test_files_for_file(file) {
if let EbiInput::Object(object, file_handler) = object {
for file_handler2 in EBI_FILE_HANDLERS {
for exporter in file_handler2.object_exporters {
if !exporter.is_portable_network_graphics() && !exporter.is_portable_document_format() {
if exporter.get_type() == importer.clone().unwrap().get_type() {
println!(
"file {}\n\tfile handler\t{}\n\timporter\t{:?}\n\tfile handler\t{}\n\texporter\t{}\n\tobject\t\t{}",
f,
file_handler,
importer,
file_handler2,
exporter,
object.get_type()
);
if importer.clone().unwrap().get_type() != object.get_type() {
assert!(false)
}
let mut c = Cursor::new(Vec::new());
println!("\tobject type\t{}", object.get_type());
exporter
.export(EbiOutput::Object(object.clone()), &mut c)
.unwrap();
}
}
}
}
}
}
});
}
#[test]
fn all_fallible_exporters() {
for (object, importer, _, f) in crate::tests::tests::get_all_test_files() {
if let EbiInput::Object(object, file_handler) = object {
for file_handler2 in EBI_FILE_HANDLERS {
for exporter in file_handler2.object_exporters_fallible {
if exporter.get_type() == importer.clone().unwrap().get_type() {
println!(
"file {}\n\tfile handler\t{}\n\timporter\t{:?}\n\tfile handler\t{}\n\texporter\t{}\n\tobject\t\t{}",
f,
file_handler,
importer,
file_handler2,
exporter,
object.get_type()
);
if importer.clone().unwrap().get_type() != object.get_type() {
assert!(false)
}
let mut c = Cursor::new(Vec::new());
println!("\tobject type\t{}", object.get_type());
let _ = exporter.export(EbiOutput::Object(object.clone()), &mut c);
}
}
}
}
}
}
#[test]
fn ebi_output() {
let mut outputs = vec![
(EbiOutput::String("bla".to_string()), "bla".to_string()),
(EbiOutput::Usize(0), "0".to_string()),
(EbiOutput::Fraction(Fraction::one()), "1".to_string()),
(EbiOutput::LogDiv(LogDiv::zero()), "0".to_string()),
(
EbiOutput::ContainsRoot(ContainsRoot::of(Root::of(Fraction::one()).unwrap())),
"1".to_string(),
),
(
EbiOutput::RootLogDiv(RootLogDiv::sqrt(LogDiv::one())),
"1".to_string(),
),
];
for (input, _, _, file) in crate::tests::tests::get_all_test_files() {
if let EbiInput::Object(object, _) = input {
outputs.push((EbiOutput::Object(object), file));
}
}
for (output, source) in outputs {
let output_type = output.get_type();
output_type.get_applicable_commands();
output_type.get_default_exporter();
output_type.to_string();
EbiCommand::select_exporter(&output_type, None, None).unwrap();
EbiCommand::select_exporter(&output_type, Some(&PathBuf::from(".xes.gz")), None)
.unwrap();
println!("source {}, output type {}", source, output.get_type());
for exporter in output_type.get_exporters() {
exporter.get_article();
exporter.get_name();
exporter.get_java_object_handlers();
exporter.get_extension();
exporter.is_binary();
exporter.to_string();
println!("\toutput {}", output);
println!("\texporter {}", exporter);
let _ = export_to_bytes(output.clone(), &exporter);
let _ = export_to_string(output.clone(), &exporter);
}
}
EbiOutputType::iter();
}
#[test]
fn unreachable_string() {
let mut f = vec![];
assert!(
EbiExporter::String
.export_from_object(EbiOutput::Usize(10), &mut f)
.is_err()
);
}
#[test]
fn unreachable_usize() {
let mut f = vec![];
assert!(
EbiExporter::Usize
.export_from_object(EbiOutput::String("a".to_string()), &mut f)
.is_err()
);
}
#[test]
fn unreachable_fraction() {
let mut f = vec![];
assert!(
EbiExporter::Fraction
.export_from_object(EbiOutput::Usize(10), &mut f)
.is_err()
);
}
#[test]
fn unreachable_logdiv() {
let mut f = vec![];
assert!(
EbiExporter::LogDiv
.export_from_object(EbiOutput::Usize(10), &mut f)
.is_err()
);
}
#[test]
fn unreachable_containsroot() {
let mut f = vec![];
assert!(
EbiExporter::ContainsRoot
.export_from_object(EbiOutput::Usize(10), &mut f)
.is_err()
);
}
#[test]
fn unreachable_rootlogdiv() {
let mut f = vec![];
assert!(
EbiExporter::RootLogDiv
.export_from_object(EbiOutput::Usize(10), &mut f)
.is_err()
);
}
}