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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! Token-efficient content compression using probabilistic template mining.
//!
//! This crate provides tools for analyzing text files, logs, and media files to extract
//! templates and metadata. It uses probabilistic template mining to compress content
//! while preserving structure, making it efficient for AI consumption.
//!
//! # Main Workflow
//!
//! 1. **Phase 1**: Initial file scan to collect statistics and prepare for processing
//! 2. **Phase 2**: Template mining and metadata extraction
//!
//! # API Example
//!
//! ```no_run
//! use zahirscan::{extract_zahir, OutputMode};
//!
//! // Process with default config (no overlay)
//! let result = extract_zahir("file.log", OutputMode::Full, None, None, &zahirscan::OutputSink::Collect)?;
//!
//! // Process with explicit config and optional output dir (None = no file write)
//! let config = zahirscan::RuntimeConfig::new();
//! let result = extract_zahir(
//! vec!["file1.log", "file2.log"],
//! OutputMode::Templates,
//! Some(&config),
//! None,
//! &zahirscan::OutputSink::Collect,
//! )?;
//! # Ok::<(), anyhow::Error>(())
//! ```
//!
//! # Stream-only example (no collection, bounded memory)
//!
//! Use [`OutputSink::StreamOnly`] to receive each `(path, Output)` in a callback; the engine does not collect.
//!
//! ```no_run
//! use std::sync::{Arc, Mutex};
//! use zahirscan::{extract_zahir, Output, OutputMode, OutputSink};
//!
//! let collected = Arc::new(Mutex::new(Vec::<(String, zahirscan::Output)>::new()));
//! let collected_clone = Arc::clone(&collected);
//! let sink = OutputSink::StreamOnly(Box::new(move |path, out| {
//! collected_clone.lock().unwrap().push((path, out));
//! }));
//! let result = extract_zahir(
//! ["file1.log", "file2.log"],
//! OutputMode::Full,
//! None,
//! None,
//! &sink,
//! )?;
//! // result.outputs is empty; collected has each (path, Output) as it completed
//! # Ok::<(), anyhow::Error>(())
//! ```
//!
//! # Streaming input
//!
//! Use [`extract_zahir_from_stream`] when paths come from a channel (e.g. nefaxer's `on_entry`
//! callback). Producer sends path strings; when the sender is dropped, zahirscan drains the
//! receiver and runs the pipeline. Pass [`OutputSink::Collect`] to get all outputs in the result, or [`OutputSink::StreamOnly`] / [`OutputSink::Channel`] to stream out.
//!
//! ```no_run
//! use std::sync::mpsc;
//! use zahirscan::{extract_zahir_from_stream, OutputMode, OutputSink};
//!
//! let (tx, rx) = mpsc::channel();
//! // In another thread: run nefaxer with on_entry: Some(|e| { tx.send(e.path.to_string_lossy().into_owned()).ok(); });
//! // Then drop(tx). This thread:
//! let result = extract_zahir_from_stream(&rx, OutputMode::Full, None, None, &OutputSink::Collect)?;
//! # Ok::<(), anyhow::Error>(())
//! ```
// Binary name
pub const PKG_NAME: &str = env!;
pub use DEFAULT_CONFIG_TOML;
// Re-export all public types and functions
pub use ;
pub use ;
pub use run_pipeline;
pub use ;
pub use ;
pub use *;
pub use OutputSink;
pub use *;
// Single entry-point API
use Result;
use debug;
use Receiver;
use ToPathIter;
/// Single entry point: extract templates and metadata from one or more files.
///
/// * `paths` - A single path or multiple paths (see [`ToPathIter`]).
/// * `mode` - Output mode (Templates or Full).
/// * `config` - If `None`, uses embedded default config only (no overlay). Overlay is for CLI via `setup::load_config()`.
/// * `output_dir` - If `Some(dir)`, writes per-file output under that directory; if `None`, skips file write (library usage) or uses temp (CLI).
/// * `output_sink` - Where results go: [`OutputSink::Collect`] (default), [`OutputSink::StreamOnly`] (callback, no collection), or [`OutputSink::Channel`] (send on channel, no collection). Pass by reference (e.g. `&OutputSink::Collect`). Errors are always in the returned [`ZahirScanResult::phase1_failed`] and [`phase2_failed`](ZahirScanResult::phase2_failed).
///
/// Returns [`ZahirScanResult`]; `outputs` is empty when using `StreamOnly` or `Channel`.
///
/// # Errors
///
/// Returns [`anyhow::Error`] when no paths are given, [`RuntimeConfig`] validation fails, or the processing pipeline fails (I/O, mmap, parsing, etc.).
///
/// # Example
///
/// See crate-level docs for examples (i.e. Collect, or `StreamOnly` / Channel).
/// Extract templates and metadata from paths received over a channel (streaming input).
///
/// Drains `paths_rx` until the sender is dropped (channel closed), then runs the same pipeline
/// as [`extract_zahir`]. Use this when paths are produced by another component (e.g. [nefaxer]'s
/// `on_entry` callback): spawn a thread that sends paths into the channel; when the producer is
/// done, drop the sender; this function then processes all received paths and streams results
/// via `on_output`.
///
/// * `paths_rx` - Reference to the channel receiver; block until closed, collecting all path strings.
/// * `mode`, `config`, `output_dir`, `output_sink` - Same as [`extract_zahir`].
///
/// # Errors
///
/// Same as [`extract_zahir`] (delegates after collecting paths from the channel).