castep_cell_io/param/general/
task.rs1use castep_cell_fmt::{Cell, CellValue, ToCell, ToCellValue};
2use castep_cell_fmt::parse::{FromCellValue, FromKeyValue};
3use castep_cell_fmt::{CResult, Error};
4use castep_cell_fmt::query::value_as_str;
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename = "TASK")]
17#[derive(Default)]
18pub enum Task {
19 #[serde(alias = "SINGLEPOINT", alias = "singlepoint")]
21 #[default]
22 SinglePoint,
23 #[serde(alias = "BANDSTRUCTURE", alias = "bandstructure")]
25 BandStructure,
26 #[serde(alias = "GEOMETRYOPTIMIZATION", alias = "geometryoptimization")]
28 GeometryOptimization,
29 #[serde(alias = "MOLECULARDYNAMICS", alias = "moleculardynamics")]
31 MolecularDynamics,
32 #[serde(alias = "OPTICS", alias = "optics")]
34 Optics,
35 #[serde(alias = "PHONON", alias = "phonon")]
37 Phonon,
38 #[serde(alias = "EFIELD", alias = "efield")]
40 Efield,
41 #[serde(alias = "PHONON+EFIELD", alias = "phonon+efield")]
43 PhononPlusEfield,
44 #[serde(alias = "TRANSITIONSTATESEARCH", alias = "transitionstatesearch")]
46 TransitionStateSearch,
47 #[serde(alias = "MAGRES", alias = "magres")]
49 MagRes,
50 #[serde(alias = "ELNES", alias = "elnes")]
52 Elnes,
53 #[serde(alias = "ELECTRONICSPECTROSCOPY", alias = "electronicspectroscopy")]
55 ElectronicSpectroscopy,
56 #[serde(alias = "AUTOSOLVATION", alias = "autosolvation")]
58 Autosolvation,
59}
60
61
62impl FromCellValue for Task {
63 fn from_cell_value(value: &CellValue<'_>) -> CResult<Self> {
64 match value_as_str(value)?.to_ascii_lowercase().as_str() {
65 "singlepoint" => Ok(Self::SinglePoint),
66 "bandstructure" => Ok(Self::BandStructure),
67 "geometryoptimization" => Ok(Self::GeometryOptimization),
68 "moleculardynamics" => Ok(Self::MolecularDynamics),
69 "optics" => Ok(Self::Optics),
70 "phonon" => Ok(Self::Phonon),
71 "efield" => Ok(Self::Efield),
72 "phonon+efield" => Ok(Self::PhononPlusEfield),
73 "transitionstatesearch" => Ok(Self::TransitionStateSearch),
74 "magres" => Ok(Self::MagRes),
75 "elnes" => Ok(Self::Elnes),
76 "electronicspectroscopy" => Ok(Self::ElectronicSpectroscopy),
77 "autosolvation" => Ok(Self::Autosolvation),
78 other => Err(Error::Message(format!("unknown Task: {other}"))),
79 }
80 }
81}
82
83impl FromKeyValue for Task {
84 const KEY_NAME: &'static str = "TASK";
85
86 fn from_cell_value_kv(value: &CellValue<'_>) -> CResult<Self> {
87 Self::from_cell_value(value)
88 }
89}
90
91impl ToCell for Task {
92 fn to_cell(&self) -> Cell<'_> {
93 Cell::KeyValue("TASK", self.to_cell_value())
94 }
95}
96
97impl ToCellValue for Task {
98 fn to_cell_value(&self) -> CellValue<'_> {
99 CellValue::String(
100 match self {
101 Task::SinglePoint => "SinglePoint",
102 Task::BandStructure => "BandStructure",
103 Task::GeometryOptimization => "GeometryOptimization",
104 Task::MolecularDynamics => "MolecularDynamics",
105 Task::Optics => "Optics",
106 Task::Phonon => "Phonon",
107 Task::Efield => "Efield",
108 Task::PhononPlusEfield => "Phonon+Efield",
109 Task::TransitionStateSearch => "TransitionStateSearch",
110 Task::MagRes => "MagRes",
111 Task::Elnes => "Elnes",
112 Task::ElectronicSpectroscopy => "ElectronicSpectroscopy",
113 Task::Autosolvation => "Autosolvation",
114 }
115 .to_string(),
116 )
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123 use castep_cell_fmt::CellValue;
124
125 #[test]
126 fn test_case_insensitive_parsing() {
127 let val = CellValue::Str("singlepoint");
128 assert_eq!(Task::from_cell_value(&val).unwrap(), Task::SinglePoint);
129
130 let val = CellValue::Str("SINGLEPOINT");
131 assert_eq!(Task::from_cell_value(&val).unwrap(), Task::SinglePoint);
132
133 let val = CellValue::Str("SinglePoint");
134 assert_eq!(Task::from_cell_value(&val).unwrap(), Task::SinglePoint);
135 }
136
137 #[test]
138 fn test_all_variants() {
139 assert_eq!(Task::from_cell_value(&CellValue::Str("bandstructure")).unwrap(), Task::BandStructure);
140 assert_eq!(Task::from_cell_value(&CellValue::Str("geometryoptimization")).unwrap(), Task::GeometryOptimization);
141 assert_eq!(Task::from_cell_value(&CellValue::Str("moleculardynamics")).unwrap(), Task::MolecularDynamics);
142 assert_eq!(Task::from_cell_value(&CellValue::Str("optics")).unwrap(), Task::Optics);
143 assert_eq!(Task::from_cell_value(&CellValue::Str("phonon")).unwrap(), Task::Phonon);
144 assert_eq!(Task::from_cell_value(&CellValue::Str("efield")).unwrap(), Task::Efield);
145 assert_eq!(Task::from_cell_value(&CellValue::Str("phonon+efield")).unwrap(), Task::PhononPlusEfield);
146 assert_eq!(Task::from_cell_value(&CellValue::Str("transitionstatesearch")).unwrap(), Task::TransitionStateSearch);
147 assert_eq!(Task::from_cell_value(&CellValue::Str("magres")).unwrap(), Task::MagRes);
148 assert_eq!(Task::from_cell_value(&CellValue::Str("elnes")).unwrap(), Task::Elnes);
149 assert_eq!(Task::from_cell_value(&CellValue::Str("electronicspectroscopy")).unwrap(), Task::ElectronicSpectroscopy);
150 assert_eq!(Task::from_cell_value(&CellValue::Str("autosolvation")).unwrap(), Task::Autosolvation);
151 }
152
153 #[test]
154 fn test_invalid_variant() {
155 let val = CellValue::Str("invalid");
156 assert!(Task::from_cell_value(&val).is_err());
157 }
158
159 #[test]
160 fn test_key_name() {
161 assert_eq!(Task::KEY_NAME, "TASK");
162 }
163}
164