mesh_loader/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use std::io;
#[cfg(any(feature = "obj", feature = "stl"))]
use std::{fmt, path::Path};

#[cfg(any(feature = "obj", feature = "stl"))]
use crate::utils::bytes::{bytecount_naive, memrchr_naive};

#[cfg(feature = "collada")]
macro_rules! format_err {
    ($msg:expr $(,)?) => {
        crate::error::invalid_data($msg)
    };
    ($($tt:tt)*) => {
        crate::error::invalid_data(format!($($tt)*))
    };
}

#[cfg(feature = "collada")]
macro_rules! bail {
    ($($tt:tt)*) => {
        return Err(format_err!($($tt)*))
    };
}

#[cold]
pub(crate) fn invalid_data(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
    let e = e.into();
    let kind = e
        .downcast_ref::<io::Error>()
        .map_or(io::ErrorKind::InvalidData, io::Error::kind);
    io::Error::new(kind, e)
}

#[cfg(any(feature = "obj", feature = "stl"))]
#[cold]
pub(crate) fn with_location(e: &io::Error, location: &Location<'_>) -> io::Error {
    io::Error::new(e.kind(), format!("{e} ({location})"))
}

#[cfg(any(feature = "obj", feature = "stl"))]
pub(crate) struct Location<'a> {
    file: Option<&'a Path>,
    line: usize,
    column: usize,
}

#[cfg(any(feature = "obj", feature = "stl"))]
impl<'a> Location<'a> {
    #[cold]
    #[inline(never)]
    pub(crate) fn find(remaining: usize, start: &[u8], file: Option<&'a Path>) -> Self {
        let pos = start.len() - remaining;
        let line = bytecount_naive(b'\n', &start[..pos]) + 1;
        let column = memrchr_naive(b'\n', &start[..pos]).unwrap_or(pos) + 1;
        Self {
            file: file.filter(|&p| p != Path::new("")),
            line,
            column,
        }
    }
}

#[cfg(any(feature = "obj", feature = "stl"))]
impl fmt::Display for Location<'_> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if let Some(file) = self.file {
            write!(f, "{}:{}:{}", file.display(), self.line, self.column)
        } else {
            write!(f, "{}:{}", self.line, self.column)
        }
    }
}