1use crate::cfg::CFG;
2use crate::gen::fs;
3use std::error::Error as StdError;
4use std::ffi::OsString;
5use std::fmt::{self, Display};
6use std::path::Path;
7
8pub(super) type Result<T, E = Error> = std::result::Result<T, E>;
9
10#[derive(Debug)]
11pub(super) enum Error {
12 NoEnv(OsString),
13 Fs(fs::Error),
14 ExportedDirNotAbsolute(&'static Path),
15 ExportedEmptyPrefix,
16 ExportedDirsWithoutLinks,
17 ExportedPrefixesWithoutLinks,
18 ExportedLinksWithoutLinks,
19 UnusedExportedPrefix(&'static str),
20 UnusedExportedLinks(&'static str),
21}
22
23macro_rules! expr {
24 ($expr:expr) => {{
25 let _ = $expr; stringify!($expr)
27 }};
28}
29
30const LINKS_DOCUMENTATION: &str =
31 "https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key";
32
33impl Display for Error {
34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
35 match self {
36 Error::NoEnv(var) => {
37 write!(f, "missing {} environment variable", var.to_string_lossy())
38 }
39 Error::Fs(err) => err.fmt(f),
40 Error::ExportedDirNotAbsolute(path) => write!(
41 f,
42 "element of {} must be absolute path, but was: `{}`",
43 expr!(CFG.exported_header_dirs),
44 path.display(),
45 ),
46 Error::ExportedEmptyPrefix => write!(
47 f,
48 "element of {} must not be empty string",
49 expr!(CFG.exported_header_prefixes),
50 ),
51 Error::ExportedDirsWithoutLinks => write!(
52 f,
53 "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
54 expr!(CFG.exported_header_dirs),
55 LINKS_DOCUMENTATION,
56 ),
57 Error::ExportedPrefixesWithoutLinks => write!(
58 f,
59 "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
60 expr!(CFG.exported_header_prefixes),
61 LINKS_DOCUMENTATION,
62 ),
63 Error::ExportedLinksWithoutLinks => write!(
64 f,
65 "if {} is nonempty then `links` needs to be set in Cargo.toml; see {}",
66 expr!(CFG.exported_header_links),
67 LINKS_DOCUMENTATION,
68 ),
69 Error::UnusedExportedPrefix(unused) => write!(
70 f,
71 "unused element in {}: {:?} does not match the include prefix of any direct dependency",
72 expr!(CFG.exported_header_prefixes),
73 unused,
74 ),
75 Error::UnusedExportedLinks(unused) => write!(
76 f,
77 "unused element in {}: {:?} does not match the `links` attribute any direct dependency",
78 expr!(CFG.exported_header_links),
79 unused,
80 ),
81 }
82 }
83}
84
85impl StdError for Error {
86 fn source(&self) -> Option<&(dyn StdError + 'static)> {
87 match self {
88 Error::Fs(err) => err.source(),
89 _ => None,
90 }
91 }
92}
93
94impl From<fs::Error> for Error {
95 fn from(err: fs::Error) -> Self {
96 Error::Fs(err)
97 }
98}