eightyseven 0.1.5

Read and write gro files, pretty quickly.
Documentation
/*!
Read and write `gro` files, pretty quickly.

A `gro` file (Gromos87) describes molecular structures in a plain-text format.
(See [the Gromacs manual][gro_man] or [the old pretty manual][gro_man_legacy].)

Note that, for now, only reading and writing of the classic fixed format is
supported. The additional precision reading mode is on the agenda.

_eightyseven_ can format the atoms section of a gro file in a parallel fashion,
with `WriteGro::write_par` and related methods.

This library comes with its own `Structure` type, which mirrors the information
that is stored in `gro` files. For `Structure`, the `ReadGro`, `WriteGro`, and
`WriteGroPar` traits are implemented. The reading and writing functionality
provided by these traits are provided as good default implementations, which
rely on a couple of easy to implement bridging functions. This makes
implementing the traits for custom types very easy.

Moreover, rather specialized readers that read only a subset of the atom line
fields can be implemented easily and efficiently by setting the flags of the
`ReadGro::PARSE_LIST` constant.

```
# use std::io;
# fn main() -> io::Result<()> {
use eightyseven::structure::Structure;

// Read the structure from a file.
use eightyseven::reader::ReadGro;
let mut structure = Structure::open_gro("tests/eq.gro")?;
println!(" title: {}", structure.title);
println!("natoms: {}", structure.natoms());

// Modify the structure.
// For example, center the structure such that the `BB` beads are centered.
let bb_positions = structure
    .atoms
    .iter()
    .filter(|&atom| atom.atomname.as_str() == "BB")
    .map(|atom| atom.position);
let bb_center = bb_positions.clone().sum::<glam::Vec3>() / bb_positions.count() as f32;

for atom in &mut structure.atoms {
    atom.position -= bb_center;
}

// And write the structure.
use eightyseven::writer::WriteGro;
structure.save_gro("eq_offset.gro")?;

// Or, for fast writing of large files, format the atom section in parallel.
use eightyseven::writer::WriteGroPar;
structure.save_gro_par("eq_offset.gro")?;

// For both single-threaded and parallel formatting, generic writers exist as well.
// They can write to any type that implements `io::Write`.
structure.write_par(&mut std::io::empty())?;
# Ok(())
# }
```

[gro_man]: https://manual.gromacs.org/current/reference-manual/file-formats.html#gro
[gro_man_legacy]: https://manual.gromacs.org/archive/5.0.3/online/gro.html

 By Marieke Westendorp, 2024.
<ma3ke.cyber@gmail.com>
*/

pub mod reader;
pub mod structure;
pub mod writer;

const GRO_INTEGER_LIMIT: u32 = 100000;

#[cfg(test)]
mod tests {
    pub(crate) const PATH: &str = "tests/eq.gro";
}