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
//! JSON envelope types for CLI output.
//!
//! When `--format json` is used, extraction results are wrapped in these envelopes
//! so tooling (such as the benchmark harness) can read timing information without
//! parsing stderr or running a separate profiling tool.
use Serialize;
use ExtractedDocument;
/// Per-stage cold-start timing breakdown for a single `xberg extract` invocation.
///
/// Only populated when stage timing is requested (see
/// [`crate::commands::extract::stage_timing_requested`]). Every duration is measured with
/// [`std::time::Instant`] (never wall-clock/system time) and reported in milliseconds.
///
/// # Stage coverage
///
/// - `process_init_ms` and `first_parse_ms` are measured directly at the CLI boundary and are
/// always accurate when this struct is present.
/// - `ort_session_and_inference_ms` is a coarse approximation: the core library does not expose
/// a public hook for ONNX Runtime session creation or first-inference timing (the closest
/// internal signal, `xberg::layout::inference_timings`, is `pub(crate)` and not reachable from
/// the CLI). When layout/OCR features that use ORT are active, this field reports the *total*
/// extraction wall time minus `first_parse_ms` as an upper bound that includes ORT session
/// creation, inference, and any other post-parse processing — it is not a clean sub-stage
/// measurement. See the doc comment on the field itself for the precise caveat.
/// Single-file extraction result with wall-clock timing.
///
/// Emitted to stdout by `xberg extract --format json`.
/// Batch extraction results with per-file and total timing.
///
/// Emitted to stdout by `xberg batch --format json`.