Skip to main content

scientific_workflow/
configuration.rs

1//! Pure fixed-and-sweep configuration expansion.
2//!
3//! The canonical API reads one directory containing exactly the parameter
4//! inputs relevant to combination expansion:
5//!
6//! ```text
7//! config/
8//! ├── fixed.json
9//! └── sweep.json
10//! ```
11//!
12//! - `fixed.json` is an arbitrarily nested object of leaves shared by every
13//!   resolved configuration.
14//! - `sweep.json` is a tagged nested Cartesian-axis or explicit-case definition.
15//!
16//! [`ConfigurationSpace`] validates those two documents and lazily produces
17//! every [`ResolvedConfiguration`]. It does not know about tasks, phases,
18//! studies, workloads, display, storage, or scientific state. Callers decide
19//! how each resolved configuration is used. The independent [`ProjectPaths`]
20//! utility strictly validates `config/paths.json` when a downstream project
21//! uses the conventional named-path document.
22//!
23//! # Basic workflow
24//!
25//! ```no_run
26//! use scientific_workflow::configuration::ConfigurationSpace;
27//!
28//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
29//! let configurations = ConfigurationSpace::load("scientific-study/config")?;
30//! for configuration in configurations.combinations() {
31//!     let (temperature, seed): (f64, u64) =
32//!         configuration.decode_values(("/temperature", "/seed"))?;
33//!     println!(
34//!         "combination={} temperature={temperature} seed={seed}",
35//!         configuration.ordinal(),
36//!     );
37//! }
38//! # Ok(())
39//! # }
40//! ```
41//!
42//! # Ownership and round trips
43//!
44//! Configuration is immutable after loading. `ConfigurationSpace`,
45//! `ResolvedConfiguration`, and `ConfigurationIter` retain shared parsed leaf
46//! allocations. Exact leaf lookup does not clone JSON. Nested subtrees spanning
47//! fixed and swept leaves are reconstructed lazily and remain ordinary nested
48//! JSON to callers.
49//!
50//! The two original validated source byte sequences are retained unchanged.
51//! [`ResolvedConfiguration::to_json`] emits one deterministic derived
52//! fixed-plus-sweep dictionary when the caller needs serialization.
53//!
54//! # Failure behavior
55//!
56//! [`ConfigurationError`] retains source paths, exact keys, combination ordinals, and
57//! underlying IO or Serde errors where applicable. Loaders never publish
58//! partially validated objects.
59
60mod error;
61mod parameter_key_tuple;
62mod parameter_path;
63mod parameter_tree;
64mod parameters;
65mod paths;
66pub(crate) mod source;
67mod sweep;
68
69pub use error::ConfigurationError;
70#[doc(hidden)]
71pub use parameter_key_tuple::ParameterKeyTuple;
72pub use parameters::{ConfigurationIter, ConfigurationSpace, ResolvedConfiguration};
73pub use paths::ProjectPaths;