Skip to main content

Engine

Struct Engine 

Source
pub struct Engine<'a> {
    pub renderer: &'a dyn Renderer,
    pub clusterer: &'a dyn WorkstreamClusterer,
    pub redactor: &'a dyn Redactor,
    pub render_profiles: bool,
}
Expand description

The orchestration engine that wires ingestors, clusterers, redactors, and renderers.

This is the main coordination layer between the CLI and the adapter crates. Construct one via Engine::new, then call Engine::run, Engine::refresh, or Engine::import to execute the pipeline.

Fields§

§renderer: &'a dyn Renderer

The renderer used to produce Markdown packets.

§clusterer: &'a dyn WorkstreamClusterer

The clusterer used to group events into workstreams.

§redactor: &'a dyn Redactor

The redactor used to produce manager/public profiles.

§render_profiles: bool

Whether manager/public profile packets should be rendered.

Implementations§

Source§

impl<'a> Engine<'a>

Source

pub fn new( renderer: &'a dyn Renderer, clusterer: &'a dyn WorkstreamClusterer, redactor: &'a dyn Redactor, ) -> Self

Create a new engine with the given renderer, clusterer, and redactor.

§Examples
use shiplog_engine::Engine;
use shiplog_ports::{Renderer, WorkstreamClusterer, Redactor};
let engine = Engine::new(renderer, clusterer, redactor);
Source

pub fn with_profile_rendering(self, render_profiles: bool) -> Self

Return an engine configured to render or skip manager/public profile packets.

Profile rendering is enabled by default. Disable it for internal-only outputs when no real redaction key is available.

Source

pub fn run( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, bundle_profile: &BundleProfile, ) -> Result<(RunOutputs, WorkstreamSource)>

Run the full pipeline: ingest → cluster → render.

Uses WorkstreamManager to respect user-curated workstreams.

§Examples
use shiplog_engine::Engine;
use shiplog_ports::{IngestOutput, Renderer, WorkstreamClusterer, Redactor};
use shiplog_schema::bundle::BundleProfile;
use std::path::Path;

let engine = Engine::new(renderer, clusterer, redactor);
let (outputs, ws_source) = engine.run(
    ingest,
    "octocat",
    "2025-01-01..2025-04-01",
    Path::new("./out/run_123"),
    false,
    &BundleProfile::Internal,
)?;
println!("Packet written to {:?}", outputs.packet_md);
Source

pub fn run_with_profile_rendering( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, bundle_profile: &BundleProfile, render_profiles: bool, ) -> Result<(RunOutputs, WorkstreamSource)>

Run the full pipeline with explicit control over manager/public profile rendering.

Set render_profiles to false for internal-only outputs when no real redaction key is available. Manager and public bundle profiles require profile rendering because those bundles include redacted packet paths.

Source

pub fn import( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, workstreams: Option<WorkstreamsFile>, bundle_profile: &BundleProfile, ) -> Result<(RunOutputs, WorkstreamSource)>

Import a pre-built ledger and run the full render pipeline.

When workstreams is Some, uses them directly (writes as curated). When None, falls through to normal clustering.

§Examples
use shiplog_engine::Engine;
use shiplog_ports::{IngestOutput, Renderer, WorkstreamClusterer, Redactor};
use shiplog_schema::bundle::BundleProfile;
use std::path::Path;

let engine = Engine::new(renderer, clusterer, redactor);
let (outputs, _) = engine.import(
    ingest,
    "octocat",
    "2025-01-01..2025-04-01",
    Path::new("./out/import_run"),
    false,
    None, // or Some(workstreams) to supply pre-built workstreams
    &BundleProfile::Internal,
)?;
Source

pub fn import_with_profile_rendering( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, workstreams: Option<WorkstreamsFile>, bundle_profile: &BundleProfile, render_profiles: bool, ) -> Result<(RunOutputs, WorkstreamSource)>

Import a pre-built ledger with explicit control over manager/public profile rendering.

Set render_profiles to false for internal-only outputs when no real redaction key is available. Manager and public bundle profiles require profile rendering because those bundles include redacted packet paths.

Source

pub fn refresh( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, bundle_profile: &BundleProfile, ) -> Result<RunOutputs>

Refresh receipts and stats without regenerating workstreams.

This preserves user curation while updating event data.

§Examples
use shiplog_engine::Engine;
use shiplog_ports::{IngestOutput, Renderer, WorkstreamClusterer, Redactor};
use shiplog_schema::bundle::BundleProfile;
use std::path::Path;

let engine = Engine::new(renderer, clusterer, redactor);
// out_dir must already contain workstreams.yaml or workstreams.suggested.yaml
let outputs = engine.refresh(
    ingest,
    "octocat",
    "2025-01-01..2025-04-01",
    Path::new("./out/existing_run"),
    false,
    &BundleProfile::Internal,
)?;
Source

pub fn refresh_with_profile_rendering( &self, ingest: IngestOutput, user: &str, window_label: &str, out_dir: &Path, zip: bool, bundle_profile: &BundleProfile, render_profiles: bool, ) -> Result<RunOutputs>

Refresh receipts and stats with explicit control over manager/public profile rendering.

Set render_profiles to false for internal-only outputs when no real redaction key is available. Manager and public bundle profiles require profile rendering because those bundles include redacted packet paths.

Source

pub fn merge( &self, ingest_outputs: Vec<IngestOutput>, resolution: ConflictResolution, ) -> Result<IngestOutput>

Merge events from multiple sources with deduplication and conflict resolution.

This function:

  • Deduplicates events by ID
  • Resolves conflicts for events that appear in multiple sources
  • Merges coverage manifests from all sources
  • Sorts events by timestamp
§Examples
use shiplog_engine::{Engine, ConflictResolution};
use shiplog_ports::{IngestOutput, Renderer, WorkstreamClusterer, Redactor};

let engine = Engine::new(renderer, clusterer, redactor);
let merged = engine.merge(
    vec![output_a, output_b],
    ConflictResolution::PreferMostRecent,
)?;
println!("Merged {} events", merged.events.len());

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for Engine<'a>

§

impl<'a> !Send for Engine<'a>

§

impl<'a> !Sync for Engine<'a>

§

impl<'a> !UnwindSafe for Engine<'a>

§

impl<'a> Freeze for Engine<'a>

§

impl<'a> Unpin for Engine<'a>

§

impl<'a> UnsafeUnpin for Engine<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.