1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// This is free and unencumbered software released into the public domain.
//! Shared batching primitives with local-execution error defaults.
//!
//! # An intermediate batch filter
//!
//! This example connects **Fetcher → Rust filter → Writer**. It assumes one
//! JSON-LD object per line with expanded type IRIs; it does not perform JSON-LD
//! context expansion. Retained lines keep their bytes and order. Batch boundaries
//! are transport groupings, not RDF graphs or transactions.
//!
//! Unlike native [`crate::Pipeline::pipe`] connections, an in-process filter is
//! passed to the next program as [`crate::GraphInput::Jsonl`]. Pulling batches
//! supplies backpressure, and source errors are propagated to the consumer.
//!
//! ```no_run
//! use asimov_runner::{
//! AnyOutput, ExecutorError, Fetcher, GraphInput, GraphOutput, JsonlBatch,
//! JsonlStream, StreamExt, Writer, stream,
//! };
//! use serde_json::Value;
//! use std::io;
//!
//! fn keep_people(batch: JsonlBatch) -> Result<JsonlBatch, ExecutorError> {
//! let mut kept = Vec::new();
//! for line in batch.into_lines() {
//! let record: Value = serde_json::from_slice(&line)
//! .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))?;
//! let wanted = "https://schema.org/Person";
//! let keep = match record.get("@type") {
//! Some(Value::String(kind)) => kind == wanted,
//! Some(Value::Array(kinds)) => kinds.iter().any(|kind| kind.as_str() == Some(wanted)),
//! _ => false,
//! };
//! if keep { kept.push(line); }
//! }
//! Ok(JsonlBatch::new(kept))
//! }
//!
//! fn people_only(mut source: JsonlStream) -> JsonlStream {
//! Box::pin(stream! {
//! while let Some(batch) = source.next().await {
//! match batch.and_then(keep_people) {
//! Ok(batch) if !batch.is_empty() => yield Ok(batch),
//! Ok(_) => {},
//! Err(error) => {
//! drop(source);
//! yield Err(error);
//! return;
//! },
//! }
//! }
//! })
//! }
//!
//! # async fn example() -> Result<(), ExecutorError> {
//! let source = Fetcher::new(
//! "asimov-example-fetcher", "https://example.com/collection",
//! GraphOutput::Captured, Default::default(),
//! ).execute().await?;
//! let exported = Writer::new(
//! "asimov-example-writer", GraphInput::Jsonl(people_only(source)),
//! AnyOutput::Captured, Default::default(),
//! ).execute().await?.into_inner();
//! # Ok(())
//! # }
//! ```
pub use ;
pub use ;
pub type BatchStream<E = crateExecutorError> = BatchStream;
pub type LineStream<E = crateExecutorError> = LineStream;
pub type FrameStream<E = crateExecutorError> = FrameStream;
pub use with_batching;