mesh_loader/stl/
error.rs

1use std::{fmt, io, path::Path};
2
3#[cfg_attr(test, derive(Debug))]
4pub(super) enum ErrorKind {
5    // ASCII STL error
6    ExpectedSpace(&'static str, usize),
7    ExpectedNewline(&'static str, usize),
8    Expected(&'static str, usize),
9    Float(usize),
10    NotAscii(&'static str, usize),
11    // binary STL error
12    TooSmall,
13    InvalidSize,
14    TooManyTriangles,
15}
16
17impl ErrorKind {
18    #[cold]
19    #[inline(never)]
20    pub(super) fn into_io_error(self, start: &[u8], path: Option<&Path>) -> io::Error {
21        let remaining = match self {
22            // ASCII STL error
23            Self::Expected(.., n)
24            | Self::ExpectedNewline(.., n)
25            | Self::ExpectedSpace(.., n)
26            | Self::Float(n)
27            | Self::NotAscii(.., n) => n,
28            // binary STL error (always points file:1:1, as error occurs only during reading the header)
29            _ => start.len(),
30        };
31        crate::error::with_location(
32            &crate::error::invalid_data(self.to_string()),
33            &crate::error::Location::find(remaining, start, path),
34        )
35    }
36}
37
38impl fmt::Display for ErrorKind {
39    #[cold]
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match *self {
42            // ASCII STL error
43            Self::ExpectedSpace(msg, ..) => {
44                if msg == "normal" || msg == "vertex" {
45                    f.write_str("expected space before floats")
46                } else {
47                    write!(f, "expected space after {msg}")
48                }
49            }
50            Self::ExpectedNewline(msg, ..) => {
51                if msg == "solid" {
52                    f.write_str("expected newline after solid name")
53                } else if msg == "normal" || msg == "vertex" {
54                    f.write_str("expected newline after floats")
55                } else {
56                    write!(f, "expected newline after {msg}")
57                }
58            }
59            Self::Expected(msg, remaining) => {
60                if msg == "solid" && remaining != 0 {
61                    f.write_str("expected solid or eof")
62                } else if msg == "endsolid" {
63                    f.write_str("expected facet normal or endsolid")
64                } else {
65                    write!(f, "expected {msg}")
66                }
67            }
68            Self::Float(..) => f.write_str("error while parsing a float"),
69            Self::NotAscii(..) => f.write_str("invalid ASCII"),
70            // binary STL error
71            Self::TooSmall => f.write_str(
72                "failed to determine STL storage representation: \
73                 not valid ASCII STL and size is too small as binary STL",
74            ),
75            Self::InvalidSize => f.write_str(
76                "failed to determine STL storage representation: \
77                 not valid ASCII STL and size is invalid as binary STL",
78            ),
79            Self::TooManyTriangles => f.write_str("too many triangles"),
80        }
81    }
82}