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