1use std::{
2 borrow::Cow,
3 fmt::{Debug, Display, Formatter},
4};
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub struct Error {
9 pub kind: Kind,
11 pub line_index: usize,
13 pub message: Option<Cow<'static, str>>,
15}
16
17impl Error {
18 #[must_use]
20 pub(crate) fn new(kind: Kind, line_index: usize, message: Option<Cow<'static, str>>) -> Self {
21 Self {
22 kind,
23 line_index,
24 message,
25 }
26 }
27
28 #[must_use]
30 pub(crate) fn with_message<M: Into<Cow<'static, str>>, O: Into<Option<M>>>(
31 kind: Kind,
32 line_index: usize,
33 message: O,
34 ) -> Self {
35 Self::new(kind, line_index, message.into().map(Into::into))
36 }
37
38 #[must_use]
40 pub(crate) fn without_message(kind: Kind, line_index: usize) -> Self {
41 Self::new(kind, line_index, None)
42 }
43}
44
45impl std::error::Error for Error {}
46
47impl Display for Error {
48 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
49 if let Some(msg) = &self.message {
50 write!(f, "{} @ ln:{} - {}", self.kind, self.line_index + 1, msg)
51 } else {
52 write!(f, "{} @ ln:{}", self.kind, self.line_index + 1,)
53 }
54 }
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58pub enum Kind {
59 Empty,
61 Missing,
63 LimitExceeded,
65 InvalidHeader,
67 InvalidCounts,
69 InvalidVertexPosition,
71 InvalidColor,
73 InvalidFace,
75 InvalidFaceIndex,
77}
78
79impl Display for Kind {
80 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
81 Debug::fmt(self, f)
82 }
83}