molframe_core/io/format/
options.rs1use super::super::input::{InputBuffer, Limits};
4use super::detect::Format;
5use crate::diagnostic::Diagnostic;
6use crate::diagnostic::{Diagnostics, Strictness};
7use crate::structure::Structure;
8
9#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
11#[non_exhaustive]
12pub enum ParseMode {
13 Strict,
15 #[default]
17 Permissive,
18 Recover,
20}
21
22impl ParseMode {
23 #[must_use]
25 pub const fn strictness(self) -> Strictness {
26 match self {
27 Self::Strict => Strictness::Strict,
28 Self::Permissive => Strictness::Medium,
29 Self::Recover => Strictness::Loose,
30 }
31 }
32}
33
34#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
36pub enum MissingElementPolicy {
37 #[default]
39 PreserveUnknown,
40 InferFromAtomName,
42}
43
44#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
46pub enum AmbiguousResidueBoundaryPolicy {
47 #[default]
49 Reject,
50 InferFromFileOrder,
52}
53
54#[derive(Clone, Debug, Default)]
56pub struct ReadOptions {
57 pub format: Format,
59 pub mode: ParseMode,
61 pub only_first_model: bool,
63 pub only_atomic_coords: bool,
65 pub discard_hydrogens: bool,
67 pub missing_element_policy: MissingElementPolicy,
69 pub ambiguous_residue_boundary_policy: AmbiguousResidueBoundaryPolicy,
71 pub limits: Limits,
73}
74
75impl ReadOptions {
76 #[must_use]
78 pub fn new() -> Self {
79 Self::default()
80 }
81
82 #[must_use]
84 pub const fn format(mut self, format: Format) -> Self {
85 self.format = format;
86 self
87 }
88
89 #[must_use]
91 pub const fn mode(mut self, mode: ParseMode) -> Self {
92 self.mode = mode;
93 self
94 }
95
96 #[must_use]
98 pub const fn only_first_model(mut self, only: bool) -> Self {
99 self.only_first_model = only;
100 self
101 }
102
103 #[must_use]
105 pub const fn only_atomic_coords(mut self, only: bool) -> Self {
106 self.only_atomic_coords = only;
107 self
108 }
109
110 #[must_use]
112 pub const fn missing_element_policy(mut self, policy: MissingElementPolicy) -> Self {
113 self.missing_element_policy = policy;
114 self
115 }
116
117 #[must_use]
119 pub const fn ambiguous_residue_boundary_policy(
120 mut self,
121 policy: AmbiguousResidueBoundaryPolicy,
122 ) -> Self {
123 self.ambiguous_residue_boundary_policy = policy;
124 self
125 }
126
127 #[must_use]
129 pub const fn discard_hydrogens(mut self, discard: bool) -> Self {
130 self.discard_hydrogens = discard;
131 self
132 }
133
134 #[must_use]
136 pub const fn limits(mut self, limits: Limits) -> Self {
137 self.limits = limits;
138 self
139 }
140
141 pub fn finish(
148 &self,
149 structure: Structure,
150 findings: impl IntoIterator<Item = Diagnostic>,
151 ) -> ReadResult {
152 let mut ordered = Diagnostics::new();
153 ordered.extend(findings);
154 let is_error = ordered.has_error(self.mode.strictness());
155 let findings = ordered.finish();
156 if is_error {
157 Err(findings)
158 } else {
159 Ok((structure, findings))
160 }
161 }
162}
163
164pub type ReadResult = Result<(Structure, Vec<Diagnostic>), Vec<Diagnostic>>;
166
167pub trait Reader {
169 const FORMAT: Format;
171
172 fn read(input: &InputBuffer, options: &ReadOptions) -> ReadResult;
178}
179
180pub trait Select {
182 fn accept_model(&self, _model: crate::index::ModelIndex) -> bool {
184 true
185 }
186
187 fn accept_chain(&self, _chain: crate::index::ChainIndex) -> bool {
189 true
190 }
191
192 fn accept_residue(&self, _residue: crate::index::ResidueIndex) -> bool {
194 true
195 }
196
197 fn accept_atom(&self, _atom: crate::index::AtomIndex) -> bool {
199 true
200 }
201}
202
203#[derive(Clone, Copy, Debug, Default)]
205pub struct SelectAll;
206
207impl Select for SelectAll {}