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
//! Script loader: parse molpack's `.inp` input format and turn it into
//! a configured [`Molpack`](crate::Molpack) plus a list of
//! [`Target`](crate::Target)s.
//!
//! Two front-end shapes are supported:
//!
//! - **Native (feature `io`)** — [`Script::build`] reads template files
//! via molrs-io and returns a ready-to-run [`BuildResult`]:
//!
//! ```ignore
//! use std::path::Path;
//! use molpack::script;
//!
//! let src = std::fs::read_to_string("mixture.inp")?;
//! let script = script::parse(&src)?;
//! let built = script.build(Path::new("."))?;
//!
//! let frame = built.packer.pack(&built.targets, built.nloop)?;
//! script::write_frame(&built.output, &frame)?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! - **Embedding hosts (any feature set)** — [`Script::lower`] returns
//! a [`ScriptPlan`] with file paths resolved but unread. The caller
//! loads each [`StructurePlan::filepath`] with its own frame loader,
//! builds a [`Target`](crate::Target), and stamps restraints via
//! [`StructurePlan::apply`]. This is what the PyO3 wheel uses, so it
//! does not have to statically link molrs-io.
//!
//! Parsing, lowering, and I/O are kept separate so embedders can
//! intercept any stage — e.g. mutate the parsed [`Script`] before
//! `lower`, attach a custom [`Handler`](crate::Handler) to the packer,
//! or route output through a different writer.
pub use BuildResult;
pub use ;
pub use ScriptError;
pub use ;
pub use ;