1use std::fmt;
2use std::num::{ParseFloatError, ParseIntError};
3
4#[derive(Debug)]
5pub enum ParseError {
6 IncompleteHeader,
7 IncompleteFrame,
8 IncompleteVelocitySection,
9 InvalidVectorLength {
10 expected: usize,
11 found: usize,
12 },
13 InvalidNumberFormat(String),
14 MissingSpecVersion,
15 UnsupportedSpecVersion(u32),
16 InvalidMetadataJson(String),
17 IncompleteForceSection,
18 IncompleteEnergySection,
19 IncompleteSection(String),
21 UnknownSection(String),
22 ValidationError(String),
23 IndexOutOfBounds {
30 index: usize,
31 len: usize,
32 },
33 MassMismatch {
38 symbol: String,
39 first_mass: f64,
40 found_mass: f64,
41 atom_index: usize,
42 },
43}
44
45impl fmt::Display for ParseError {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 match self {
48 ParseError::IncompleteHeader => {
49 write!(f, "file ended unexpectedly while parsing frame header")
50 }
51 ParseError::IncompleteFrame => {
52 write!(f, "file ended unexpectedly while reading atom data")
53 }
54 ParseError::IncompleteVelocitySection => {
55 write!(f, "file ended unexpectedly while reading velocity section")
56 }
57 ParseError::InvalidVectorLength { expected, found } => {
58 write!(f, "expected {expected} values on line, found {found}")
59 }
60 ParseError::InvalidNumberFormat(msg) => {
61 write!(f, "invalid number format: {msg}")
62 }
63 ParseError::MissingSpecVersion => {
64 write!(
65 f,
66 "line 1 must be a JSON object containing \"con_spec_version\""
67 )
68 }
69 ParseError::UnsupportedSpecVersion(v) => {
70 write!(f, "unsupported con_spec_version: {v}")
71 }
72 ParseError::InvalidMetadataJson(msg) => {
73 write!(f, "invalid JSON metadata on line 1: {msg}")
74 }
75 ParseError::IncompleteForceSection => {
76 write!(f, "file ended unexpectedly while reading force section")
77 }
78 ParseError::IncompleteEnergySection => {
79 write!(f, "file ended unexpectedly while reading energy section")
80 }
81 ParseError::IncompleteSection(name) => {
82 write!(f, "file ended unexpectedly while reading {name} section")
83 }
84 ParseError::UnknownSection(name) => {
85 write!(f, "unknown section type in metadata: {name}")
86 }
87 ParseError::ValidationError(msg) => {
88 write!(f, "CON validation failed: {msg}")
89 }
90 ParseError::IndexOutOfBounds { index, len } => {
91 write!(
92 f,
93 "atom index {index} is out of bounds (builder holds {len} atoms)"
94 )
95 }
96 ParseError::MassMismatch {
97 symbol,
98 first_mass,
99 found_mass,
100 atom_index,
101 } => {
102 write!(
103 f,
104 "atoms of type {symbol} have inconsistent masses: first {first_mass}, atom {atom_index} has {found_mass} (CON stores one mass per type)"
105 )
106 }
107 }
108 }
109}
110
111impl std::error::Error for ParseError {}
112
113impl From<ParseFloatError> for ParseError {
114 fn from(e: ParseFloatError) -> Self {
115 ParseError::InvalidNumberFormat(e.to_string())
116 }
117}
118
119impl From<ParseIntError> for ParseError {
120 fn from(e: ParseIntError) -> Self {
121 ParseError::InvalidNumberFormat(e.to_string())
122 }
123}
124
125impl From<serde_json::Error> for ParseError {
126 fn from(e: serde_json::Error) -> Self {
127 ParseError::InvalidMetadataJson(e.to_string())
128 }
129}