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
// Copyright 2024-2026 Jonathan Shook
// SPDX-License-Identifier: Apache-2.0
//! # nmbrs-workload
//!
//! Contract & axioms: [SRD 25](../../docs/SRD/25_workload_contract.md).
//!
//! Workload specification parsing and processing for nmbrs. Owns
//! the YAML schema definition (op templates, bindings, phases,
//! scenarios, tags, parameter inheritance) plus the inline
//! `op='...'` shorthand the CLI accepts in place of a workload
//! file.
//!
//! The crate's deliberately one-way: it parses YAML / inline
//! shorthand into a [`model::Workload`] tree and exposes helpers
//! to extract bind-points, tag-filter ops, and resolve template
//! parameters. It does not execute anything — that's
//! `nmbrs-runtime`'s job.
//!
//! ## Pieces
//!
//! - [`model`] — the parsed `Workload` AST. `Workload` →
//! `WorkloadPhase`s + ops + `ScenarioNode`s; an op carries its
//! field map plus parsed bindings.
//! - [`parse`] — YAML → `Workload`, with phase-name preservation
//! and friendly error messages.
//! - [`inline`] — `nmbrs run op='hello {{cycle}}'` synthesizer:
//! builds a one-op `Workload` from a single CLI string.
//! - [`bindpoints`] — extracts `{name}`, `{{expr}}`, qualified
//! refs (`{coord:cycle}`, `{capture:foo}`) from any string.
//! - [`tags`] — `tags=block:main,phase:read` filters during op
//! selection.
//! - [`template`] — `{param}` template substitution with
//! default-value support.
//!
//! ## Quick examples
//!
//! Bind-point extraction:
//!
//! ```
//! use nmbrs_workload::bindpoints::{extract_bind_points, BindPoint, BindQualifier};
//!
//! let pts = extract_bind_points("INSERT INTO t VALUES ({id}, {{hash(cycle)}})");
//! assert_eq!(pts.len(), 2);
//! assert!(matches!(
//! &pts[0],
//! BindPoint::Reference { name, qualifier: BindQualifier::None, .. } if name == "id",
//! ));
//! assert!(matches!(&pts[1], BindPoint::InlineDefinition(expr) if expr == "hash(cycle)"));
//! ```
//!
//! Template substitution at workload-build time:
//!
//! ```
//! use nmbrs_workload::template::expand_templates;
//! use std::collections::HashMap;
//!
//! let mut params = HashMap::new();
//! params.insert("table".into(), "users".into());
//! let resolved = expand_templates(
//! "SELECT * FROM TEMPLATE(table,defaultvalue)",
//! ¶ms,
//! );
//! assert_eq!(resolved, "SELECT * FROM users");
//! ```
//!
//! ## See also
//!
//! - SRD 20 (`docs/SRD/20_workload_model.md`) — workload model
//! - SRD 21 (`docs/SRD/21_parameters.md`) — parameter resolution
//! precedence
//! - SRD 18 (`docs/SRD/18_control_flow.md`) — scenario-tree
//! constructs (`for_each`, `do_while`, `do_until`,
//! `for_combinations`)
/// SRD-85 bundled-workload catalog (embedded workloads,
/// tiers, exact-name lookup).
/// SRD-109 driver manifests (`driver=<name>` → adapter + library
/// + defaults).
/// SRD-85 deep workload suggestions — the shared "did you mean"
/// set over the local file hierarchy and the bundled catalog,
/// used by completion and the resolver not-found paths.