marque_engine/pipeline.rs
1// SPDX-FileCopyrightText: 2026 Knitli Inc.
2//
3// SPDX-License-Identifier: LicenseRef-MarqueLicense-1.0
4
5//! Async stream pipeline types.
6//!
7//! The full pipeline:
8//! Source → TextStream → SpanStream → AttributeStream → DiagnosticStream → Sink
9//!
10//! Each stage is a `Stream`. Middleware inserts between stages.
11//! This module defines the stage types; full async streaming implementation is TODO.
12
13use marque_ism::MarkingCandidate;
14use marque_rules::Diagnostic;
15
16/// Error type for stream sources.
17#[derive(Debug, thiserror::Error)]
18pub enum SourceError {
19 /// Standard I/O errors from underlying readers.
20 #[error("I/O error: {0}")]
21 Io(#[from] std::io::Error),
22 /// Other errors.
23 #[error("Source error: {0}")]
24 Other(String),
25}
26
27/// A chunk of source text with its byte offset in the original document.
28#[derive(Debug)]
29pub struct TextChunk {
30 pub offset: usize,
31 pub data: Vec<u8>,
32}
33
34/// A stream source — anything that produces `TextChunk`s.
35/// Implemented by: string buffer (WASM/server), file reader (CLI/batch), HTTP body.
36pub trait Source: futures_core::Stream<Item = Result<TextChunk, SourceError>> + Send {}
37
38impl<T> Source for T where T: futures_core::Stream<Item = Result<TextChunk, SourceError>> + Send {}
39
40/// A stream sink — anything that consumes pipeline output.
41pub trait Sink: Send {
42 fn accept_diagnostic(&mut self, diag: Diagnostic);
43 fn accept_candidate(&mut self, candidate: MarkingCandidate);
44}