Skip to main content

molframe_cif/reader/
structure.rs

1//! The entry point: bytes in, structure and findings out.
2
3use crate::document::Document;
4use crate::lower::lower;
5use crate::parser::parse;
6use molframe_core::io::{Format, InputBuffer, ReadOptions, ReadResult, Reader};
7
8/// The reader for PDBx/mmCIF.
9#[derive(Clone, Copy, Debug, Default)]
10pub struct CifReader;
11
12impl Reader for CifReader {
13    const FORMAT: Format = Format::Mmcif;
14
15    fn read(input: &InputBuffer, options: &ReadOptions) -> ReadResult {
16        read(input, options)
17    }
18}
19
20/// Reads a structure.
21///
22/// Findings from both steps are returned together: what was wrong with the file
23/// as text, and what had to be decided while interpreting it.
24///
25/// # Errors
26///
27/// Returns the findings that stopped the read.
28pub fn read(input: &InputBuffer, options: &ReadOptions) -> ReadResult {
29    super::direct::read(input, options)
30}
31
32/// Reads a structure while retaining selected non-coordinate categories.
33///
34/// `keep_category` is applied in addition to the bounded set required by core
35/// structure lowering. The returned document preserves the selected categories'
36/// values and order but is not a lossless representation of the source. Use
37/// [`read_with_document`] when every category must survive a round trip.
38///
39/// # Errors
40///
41/// Returns the findings that stopped parsing or lowering.
42#[doc(hidden)]
43pub fn read_with_metadata(
44    input: &InputBuffer,
45    options: &ReadOptions,
46    keep_category: fn(&str) -> bool,
47) -> Result<
48    (
49        Document,
50        molframe_core::Structure,
51        Vec<molframe_core::Diagnostic>,
52    ),
53    Vec<molframe_core::Diagnostic>,
54> {
55    super::direct::read_with_metadata(input, options, keep_category)
56}
57
58/// Result of a combined structure read and external event projection.
59#[doc(hidden)]
60pub type ProjectedReadResult<T> = Result<
61    (
62        Document,
63        molframe_core::Structure,
64        T,
65        Vec<molframe_core::Diagnostic>,
66    ),
67    Vec<molframe_core::Diagnostic>,
68>;
69
70/// Reads a structure and an external event projection in one lexer traversal.
71///
72/// The projection receives only categories it accepts and never requires a
73/// lossless document for those values. Selected metadata for other domain
74/// extensions remains available in the returned document.
75///
76/// # Errors
77///
78/// Returns findings that stopped CIF parsing or structure lowering.
79#[doc(hidden)]
80pub fn read_with_projection<S>(
81    input: &InputBuffer,
82    options: &ReadOptions,
83    keep_category: fn(&str) -> bool,
84    projection: S,
85) -> ProjectedReadResult<S::Output>
86where
87    S: crate::CifEventSink,
88{
89    super::direct::read_with_projection(input, options, keep_category, projection)
90}
91
92/// Reads both the lossless document and its normalised structure in one parse.
93///
94/// This is the integration seam for domain crates that interpret additional
95/// categories without reparsing the input.
96///
97/// # Errors
98///
99/// Returns the findings that stopped parsing or lowering.
100pub fn read_with_document(
101    input: &InputBuffer,
102    options: &ReadOptions,
103) -> Result<
104    (
105        Document,
106        molframe_core::Structure,
107        Vec<molframe_core::Diagnostic>,
108    ),
109    Vec<molframe_core::Diagnostic>,
110> {
111    let (document, mut findings) = parse(input)?;
112    let (structure, interpretation) = lower(&document, options)?;
113    findings.extend(interpretation);
114    options
115        .finish(structure, findings)
116        .map(|(structure, findings)| (document, structure, findings))
117}
118
119#[cfg(test)]
120#[path = "structure_tests.rs"]
121mod tests;