Library architecture¶
1 Overview¶
readcon-core is structured as an hourglass API: a Rust core with thin FFI and language-specific wrapper layers.
Python (PyO3) Julia (ccall) C++ (RAII header)
\ | /
\ | /
+------- C FFI (ffi.rs) -----+
|
Rust core library
types | parser | writer | iterators
2 Core types (types.rs)¶
FrameHeader9-line header metadata (cell, angles, atom counts, masses, specversion, metadata). The
spec_versionfield (u32) records the CON spec version from the JSON metadata line. Themetadatafield (BTreeMap<String, serde_json::Value>) holds additional key-value pairs from the JSON, preserving unrecognized keys through round-trips.AtomDatumSingle atom data (symbol, coordinates, fixed flag, atomid(original atom index before type-based reordering), optional velocities).
ConFrameComplete frame (header + atom data vector).
ConFrameBuilderBuilder pattern for constructing frames programmatically. Accepts an optional
metadatamap; the builder always setsspec_versiontoCON_SPEC_VERSION.
Symbol strings use Rc<String> to avoid per-atom string clones
within a type block.
3 Parser (parser.rs)¶
parse_line_of_n<T>Generic whitespace-separated value parser for header lines.
parse_line_of_n_f64fast-float2 specialized parser for the coordinate/velocity hot path.
parse_line_of_range_f64Flexible parser accepting between
minandmaxcolumns, padding from defaults. Used for atom lines where column 5 (atomid) is optional.parse_frame_headerConsumes 9 header lines. Detects JSON metadata on line 2 (starts with
{) for spec v2+; non-JSON line 2 triggers legacy mode (spec_version = 1). Malformed JSON (starts with{but invalid) produces an error.parse_single_frameHeader + coordinate blocks. Accepts 4-column atom lines (column 5 defaults to sequential index).
parse_velocity_sectionOptional velocity blocks after coordinates (detected by blank separator).
4 Writer (writer.rs)¶
ConFrameWriter<W: Write>Generic buffered writer.
Line 2 is always serialized as a JSON object containing
con_spec_versionplus any entries fromframe.header.metadata. The originalprebox_header[1]value is overwritten.Writes header, coordinate blocks, and velocity blocks (if
frame.has_velocities()).
5 Iterators (iterators.rs)¶
ConFrameIteratorLazy frame-by-frame parser with
next()andforward()(skip without parsing atom data).read_all_frames()Convenience function using memmap2 for large trajectory files.
parse_frames_parallel()Rayon-based parallel parsing behind the
parallelfeature gate.
6 FFI layer (ffi.rs)¶
Opaque handle pattern:
RKRConFrameOpaque Rust frame handle.
CFrame/CAtomTransparent C structs for direct data access.
Iterator lifecycle:
read_con_file_iterator->con_frame_iterator_next->rkr_frame_to_c_frame->free_c_frame->free_rkr_frame->free_con_frame_iterator.
Version and spec constants:
#define RKR_CON_SPEC_VERSION 2Compile-time spec version for
#ifguards.rkr_con_spec_version()Runtime library spec version query.
rkr_library_version()Returns library version string (e.g.
"0.5.2"). The pointer is static; do not free it.
Per-frame metadata accessors:
rkr_frame_spec_version(handle)Returns the spec version stored in a parsed frame’s header (the version the file was written with, not the library’s version).
rkr_frame_metadata_json(handle)Returns the full JSON metadata line as a heap-allocated C string. The caller must free with
rkr_free_string().
7 C++ wrapper (readcon-core.hpp)¶
Header-only RAII wrappers with lazy caching:
ConFrameIteratorRange-based for loop support.
ConFrameCached accessors for cell, angles, atoms, headers.
ConFrameWriterRAII file writer.