1pub mod anisotropic;
8pub mod atom;
10pub mod connect;
12pub mod crystal;
14pub mod dbref;
16pub mod het;
18pub mod hetnam;
20pub mod model;
22pub mod modres;
24pub mod mtrixn;
26pub mod nummdl;
28pub mod origxn;
30pub mod scalen;
32pub mod seqadv;
34pub mod seqres;
36pub mod term;
38
39#[cfg(feature = "serde")]
40use serde::{Deserialize, Serialize};
41
42#[cfg(feature = "python")]
43use pyo3::prelude::*;
44
45#[derive(Debug)]
86#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
87#[cfg_attr(feature = "python", pyclass)]
88pub enum Record {
89 Anisou(anisotropic::AnisotropicRecord),
91 Atom(atom::AtomRecord),
93 Connect(connect::ConnectRecord),
95 Crystal(crystal::CrystalRecord),
97 DBRef(dbref::DBRefRecord),
99 Het(het::HetRecord),
101 Hetatm(atom::AtomRecord),
103 Hetnam(hetnam::HetnamRecord),
105 Nummdl(nummdl::NummdlRecord),
107 MtrixN(mtrixn::MtrixN),
109 Model(model::ModelRecord),
111 Modres(modres::ModresRecord),
113 OrigxN(origxn::OrigxN),
115 ScaleN(scalen::ScaleN),
117 Seqres(seqres::SeqresRecord),
119 Seqadv(seqadv::SeqAdvRecord),
121 Term(term::TermRecord),
123 Endmdl(),
125}
126#[cfg(feature = "python")]
127macro_rules! debug_match {
128 ($self:expr, { $($variant:ident($value:ident)),* }) => {
129 match $self {
130 $(Self::$variant($value) => format!("{:?}", $value),)*
131 Self::Endmdl() => "ENDMDL".to_string(),
132 }
133 };
134}
135
136#[cfg(feature = "python")]
137#[pymethods]
138impl Record {
139 #[new]
140 fn python_new(str: &str) -> Self {
141 match Self::try_from(str) {
142 Ok(item) => item,
143 Err(_) => panic!("Unable to parse line"),
144 }
145 }
146 #[getter]
147 fn record(&self, py: Python) -> Py<PyAny> {
148 match self {
149 Self::Atom(atom) => atom.clone().into_pyobject(py).unwrap().into_any().into(),
150 Self::Anisou(anisou) => anisou.clone().into_pyobject(py).unwrap().into_any().into(),
151 Self::Connect(connect) => connect.clone().into_pyobject(py).unwrap().into_any().into(),
152 Self::Crystal(crystal) => crystal.clone().into_pyobject(py).unwrap().into_any().into(),
153 Self::DBRef(dbref) => dbref.clone().into_pyobject(py).unwrap().into_any().into(),
154 Self::Endmdl() => py.None(),
155 Self::Hetatm(atom) => atom.clone().into_pyobject(py).unwrap().into_any().into(),
156 Self::Het(het) => het.clone().into_pyobject(py).unwrap().into_any().into(),
157 Self::Hetnam(hetnam) => hetnam.clone().into_pyobject(py).unwrap().into_any().into(),
158 Self::Nummdl(nummdl) => nummdl.clone().into_pyobject(py).unwrap().into_any().into(),
159 Self::Model(model) => model.clone().into_pyobject(py).unwrap().into_any().into(),
160 Self::Modres(modres) => modres.clone().into_pyobject(py).unwrap().into_any().into(),
161 Self::MtrixN(mtrix) => mtrix.clone().into_pyobject(py).unwrap().into_any().into(),
162 Self::OrigxN(origxn) => origxn.clone().into_pyobject(py).unwrap().into_any().into(),
163 Self::ScaleN(scalen) => scalen.clone().into_pyobject(py).unwrap().into_any().into(),
164 Self::Seqadv(seqadv) => seqadv.clone().into_pyobject(py).unwrap().into_any().into(),
165 Self::Seqres(seqres) => seqres.clone().into_pyobject(py).unwrap().into_any().into(),
166 Self::Term(term) => term.clone().into_pyobject(py).unwrap().into_any().into(),
167 }
168 }
169
170 fn __repr__(&self) -> String {
171 debug_match!(
172 self,
173 {
174 Anisou(anisou),
175 Atom(atom),
176 Connect(connect),
177 Crystal(crystal),
178 DBRef(dbref),
179 Het(het),
180 Hetatm(atom),
181 Hetnam(hetnam),
182 Model(model),
183 Modres(modres),
184 MtrixN(mtrix),
185 Nummdl(nummdl),
186 OrigxN(origxn),
187 ScaleN(scalen),
188 Seqadv(seqadv),
189 Seqres(seqres),
190 Term(term)
191 }
192
193 )
194 }
195}
196
197impl TryFrom<&str> for Record {
198 type Error = &'static str;
199
200 fn try_from(line: &str) -> Result<Self, Self::Error> {
230 match &line.get(0..6) {
231 Some(item) => match *item {
232 "ANISOU" => Ok(Record::Anisou(anisotropic::AnisotropicRecord::from(line))),
233 "ATOM " => Ok(Record::Atom(atom::AtomRecord::from(line))),
234 "CONECT" => Ok(Record::Connect(connect::ConnectRecord::from(line))),
235 "CRYST1" => Ok(Record::Crystal(crystal::CrystalRecord::from(line))),
236 "DBREF " => Ok(Record::DBRef(dbref::DBRefRecord::from(line))),
237 "ENDMDL" => Ok(Record::Endmdl()),
238 "HETATM" => Ok(Record::Hetatm(atom::AtomRecord::from(line))),
239 "HET " => Ok(Record::Het(het::HetRecord::from(line))),
240 "HETNAM" => Ok(Record::Hetnam(hetnam::HetnamRecord::from(line))),
241 "MTRIX1" | "MTRIX2" | "MTRIX3" => Ok(Record::MtrixN(mtrixn::MtrixN::from(line))),
242 "MODEL " => Ok(Record::Model(model::ModelRecord::from(line))),
243 "MODRES" => Ok(Record::Modres(modres::ModresRecord::from(line))),
244 "NUMMDL" => Ok(Record::Nummdl(nummdl::NummdlRecord::from(line))),
245 "ORIGX1" | "ORIGX2" | "ORIGX3" => Ok(Record::OrigxN(origxn::OrigxN::from(line))),
246 "SCALE1" | "SCALE2" | "SCALE3" => Ok(Record::ScaleN(scalen::ScaleN::from(line))),
247 "SEQRES" => Ok(Record::Seqres(seqres::SeqresRecord::from(line))),
248 "TER " => Ok(Record::Term(term::TermRecord::from(line))),
249 _ => Err("Unknown record type"),
250 },
251 None => Err("Unable to parse line"),
252 }
253 }
254}
255
256impl std::fmt::Display for Record {
257 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
258 #[cfg(feature = "serde")]
259 match serde_json::to_string(&self) {
260 Ok(item) => write!(f, "{}", item),
261 Err(_) => Err(std::fmt::Error),
262 }
263 #[cfg(not(feature = "serde"))]
264 match self {
265 Record::Anisou(anisotropic) => write!(f, "{:?}", anisotropic),
266 Record::Atom(atom) => write!(f, "{:?}", atom),
267 Record::Connect(connect) => write!(f, "{:?}", connect),
268 Record::Crystal(crystal) => write!(f, "{:?}", crystal),
269 Record::DBRef(dbref) => write!(f, "{:?}", dbref),
270 Record::Endmdl() => write!(f, "ENDMDL"),
271 Record::Hetatm(atom) => write!(f, "{:?}", atom),
272 Record::Hetnam(hetnam) => write!(f, "{:?}", hetnam),
273 Record::Het(het) => write!(f, "{:?}", het),
274 Record::MtrixN(mtrix) => write!(f, "{:?}", mtrix),
275 Record::Model(model) => write!(f, "{:?}", model),
276 Record::Modres(modres) => write!(f, "{:?}", modres),
277 Record::Nummdl(nummdl) => write!(f, "{:?}", nummdl),
278 Record::OrigxN(origxn) => write!(f, "{:?}", origxn),
279 Record::ScaleN(scalen) => write!(f, "{:?}", scalen),
280 Record::Seqres(seqres) => write!(f, "{:?}", seqres),
281 Record::Seqadv(seqadv) => write!(f, "{:?}", seqadv),
282 Record::Term(term) => write!(f, "{:?}", term),
283 }
284 }
285}
286
287