process_mining 0.6.0

Process Mining library for working with (object-centric) event data
Documentation
#![warn(
    clippy::doc_markdown,
    missing_debug_implementations,
    rust_2018_idioms,
    missing_docs,
    clippy::redundant_clone,
    clippy::clone_on_copy
)]
#![doc = include_str!("../README.md")]

pub mod analysis;
pub mod conformance;
pub mod core;
pub mod discovery;
pub mod utils;

pub use core::io::{Exportable, Importable};

// Re-export main structs for convenience
pub use core::{EventLog, PetriNet, OCEL};

// Re-export OCEL backend traits and the streaming entry points.
pub use core::event_data::object_centric::{
    appendable::AppendableOCEL,
    ocel_json::import_ocel_json_into,
    ocel_xml::xml_ocel_import::{import_ocel_xml_into, OCELImportOptions},
    readable::{OCELLookup, ReadableOCEL},
};

// Re-exported so callers can construct the `Reader` / `Writer` arguments accepted by
// `import_ocel_xml_into` and `XMLWriterWrapper` without taking a direct `quick-xml`
// dependency.
pub use quick_xml::{Reader as XmlReader, Writer as XmlWriter};

/// Bindings
pub mod bindings;

/// Used for internal testing
#[doc(hidden)]
pub mod test_utils {
    use std::path::PathBuf;

    use crate::OCEL;

    /// Get the base path for test data.
    ///
    ///  Used for internal testing
    #[allow(unused)]
    pub fn get_test_data_path() -> PathBuf {
        std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("test_data")
    }

    /// Sort all collections inside an [`OCEL`] (events, objects, types,
    /// relationships, attributes) by stable keys so two OCELs that are
    /// structurally equivalent but inserted in different orders compare
    /// equal via `assert_eq!`.
    #[allow(unused)]
    pub fn sort_ocel_for_equality_compare(ocel: &mut OCEL) {
        ocel.events
            .sort_by(|x, y| (x.time, &x.id).cmp(&(y.time, &y.id)));
        ocel.objects.sort_by(|x, y| x.id.cmp(&y.id));
        ocel.event_types.sort_by(|x, y| x.name.cmp(&y.name));
        ocel.object_types.sort_by(|x, y| x.name.cmp(&y.name));
        for e in &mut ocel.events {
            e.relationships
                .sort_by(|x, y| (&x.object_id, &x.qualifier).cmp(&(&y.object_id, &y.qualifier)));
        }
        for o in &mut ocel.objects {
            o.attributes
                .sort_by(|x, y| (x.time, &x.name).cmp(&(y.time, &y.name)));
            o.relationships
                .sort_by(|x, y| (&x.object_id, &x.qualifier).cmp(&(&y.object_id, &y.qualifier)));
        }
    }
}

/// A wrapper for either an owned or mutable reference to a [`quick_xml::Writer`]
#[allow(missing_debug_implementations)]
pub enum XMLWriterWrapper<'a, W> {
    /// Owned [`quick_xml::Writer`]
    Owned(quick_xml::Writer<W>),
    /// Mutable Reference to [`quick_xml::Writer`]
    Ref(&'a mut quick_xml::Writer<W>),
}

impl<'a, W> XMLWriterWrapper<'a, W> {
    /// Return a mutable reference to a [`quick_xml::Writer`]
    pub fn to_xml_writer(&'a mut self) -> &'a mut quick_xml::Writer<W> {
        match self {
            XMLWriterWrapper::Owned(w) => w,
            XMLWriterWrapper::Ref(w) => w,
        }
    }
}

impl<W: std::io::Write> From<W> for XMLWriterWrapper<'_, W> {
    fn from(w: W) -> Self {
        Self::Owned(quick_xml::Writer::new(w))
    }
}

impl<'a, W> From<&'a mut quick_xml::Writer<W>> for XMLWriterWrapper<'a, W> {
    fn from(w: &'a mut quick_xml::Writer<W>) -> Self {
        Self::Ref(w)
    }
}

// Not used yet, but maybe useful in the future:

// /// A wrapper for either an owned or mutable reference to a [`quick_xml::Reader`]
// #[allow(missing_debug_implementations)]
// pub enum XMLReaderWrapper<'a, R> {
//     /// Owned [`quick_xml::Reader`]
//     Owned(quick_xml::Reader<R>),
//     /// Mutable Reference to [`quick_xml::Reader`]
//     Ref(&'a mut quick_xml::Reader<R>),
// }

// impl<'a, R> XMLReaderWrapper<'a, R> {
//     /// Return a mutable reference to a [`quick_xml::Reader`]
//     pub fn to_xml_reader(&'a mut self) -> &mut quick_xml::Reader<R> {
//         match self {
//             XMLReaderWrapper::Owned(r) => r,
//             XMLReaderWrapper::Ref(r) => r,
//         }
//     }
// }

// impl<'a, R: std::io::Read> From<R> for XMLReaderWrapper<'a, R> {
//     fn from(r: R) -> Self {
//         Self::Owned(quick_xml::Reader::from_reader(r))
//     }
// }

// impl<'a, R> From<&'a mut quick_xml::Reader<R>> for XMLReaderWrapper<'a, R> {
//     fn from(w: &'a mut quick_xml::Reader<R>) -> Self {
//         Self::Ref(w)
//     }
// }