Skip to main content

molpack/script/
mod.rs

1//! Script loader: parse molpack's `.inp` input format and turn it into
2//! a configured [`Molpack`](crate::Molpack) plus a list of
3//! [`Target`](crate::Target)s.
4//!
5//! Two front-end shapes are supported:
6//!
7//! - **Native (feature `io`)** — [`Script::build`] reads template files
8//!   via molrs-io and returns a ready-to-run [`BuildResult`]:
9//!
10//!   ```ignore
11//!   use std::path::Path;
12//!   use molpack::script;
13//!
14//!   let src = std::fs::read_to_string("mixture.inp")?;
15//!   let script = script::parse(&src)?;
16//!   let built = script.build(Path::new("."))?;
17//!
18//!   let frame = built.packer.pack(&built.targets, built.nloop)?;
19//!   script::write_frame(&built.output, &frame)?;
20//!   # Ok::<(), Box<dyn std::error::Error>>(())
21//!   ```
22//!
23//! - **Embedding hosts (any feature set)** — [`Script::lower`] returns
24//!   a [`ScriptPlan`] with file paths resolved but unread. The caller
25//!   loads each [`StructurePlan::filepath`] with its own frame loader,
26//!   builds a [`Target`](crate::Target), and stamps restraints via
27//!   [`StructurePlan::apply`]. This is what the PyO3 wheel uses, so it
28//!   does not have to statically link molrs-io.
29//!
30//! Parsing, lowering, and I/O are kept separate so embedders can
31//! intercept any stage — e.g. mutate the parsed [`Script`] before
32//! `lower`, attach a custom [`Handler`](crate::Handler) to the packer,
33//! or route output through a different writer.
34
35mod build;
36mod error;
37#[cfg(feature = "io")]
38mod io;
39mod parser;
40
41#[cfg(feature = "io")]
42pub use build::BuildResult;
43pub use build::{ScriptPlan, StructurePlan};
44pub use error::ScriptError;
45#[cfg(feature = "io")]
46pub use io::{read_frame, write_frame};
47pub use parser::{AtomGroup, PbcSpec, RestraintSpec, Script, Structure, parse};