Skip to main content

imping_build/
error.rs

1//! Error type.
2
3use core::fmt;
4use std::path::PathBuf;
5
6/// Why generating bindings failed.
7///
8/// Messages name the file involved.
9#[derive(Debug)]
10#[non_exhaustive]
11pub enum Error {
12    /// The IR file could not be read.
13    Read {
14        /// The IR file.
15        path: PathBuf,
16        /// The I/O error.
17        source: std::io::Error,
18    },
19    /// The IR file is not valid IR.
20    Parse {
21        /// The IR file.
22        path: PathBuf,
23        /// Why it could not be parsed.
24        source: imping_ir::Error,
25    },
26    /// Bindings could not be generated from the IR files.
27    Generate {
28        /// The first IR file; `source` names the build involved.
29        path: PathBuf,
30        /// Why generation failed.
31        source: imping_codegen::Error,
32    },
33    /// The bindings could not be written.
34    Write {
35        /// The file being written.
36        path: PathBuf,
37        /// The I/O error.
38        source: std::io::Error,
39    },
40    /// [`Builder::generate`](crate::Builder::generate) was called outside a
41    /// build script, where `OUT_DIR` is not set.
42    OutDirNotSet,
43}
44
45impl fmt::Display for Error {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        match self {
48            Error::Read { path, source } => {
49                write!(f, "failed to read IR file `{}`: {source}", path.display())
50            }
51            Error::Parse { path, source } => {
52                write!(f, "`{}` is not a valid IR file: {source}", path.display())?;
53                // The cause chain has the JSON line and column to fix.
54                let mut cause = core::error::Error::source(source);
55                while let Some(error) = cause {
56                    write!(f, ": {error}")?;
57                    cause = error.source();
58                }
59                Ok(())
60            }
61            Error::Generate { path, source } => write!(
62                f,
63                "failed to generate bindings from `{}`: {source}",
64                path.display()
65            ),
66            Error::Write { path, source } => {
67                write!(f, "failed to write `{}`: {source}", path.display())
68            }
69            Error::OutDirNotSet => f.write_str(
70                "OUT_DIR is not set; `generate()` is for build.rs, use `generate_to(path)` elsewhere",
71            ),
72        }
73    }
74}
75
76impl core::error::Error for Error {
77    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
78        match self {
79            Error::Read { source, .. } | Error::Write { source, .. } => Some(source),
80            Error::Parse { source, .. } => Some(source),
81            Error::Generate { source, .. } => Some(source),
82            Error::OutDirNotSet => None,
83        }
84    }
85}