1use std::{fmt::Display, io};
2
3#[derive(Debug)]
5pub enum Error {
6 Io(io::Error),
8 Protoc(String),
10 Field {
12 package: String,
14 message: String,
16 field: String,
18 text: String,
20 },
21 Message {
23 package: String,
25 message: String,
27 text: String,
29 },
30 Package {
32 package: String,
34 text: String,
36 },
37 #[cfg(feature = "config-file")]
38 ConfigFile {
40 file_name: std::path::PathBuf,
42 err: toml::de::Error,
44 },
45}
46
47pub type Result<T> = std::result::Result<T, Error>;
49
50impl Display for Error {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 match self {
53 Error::Io(error) => error.fmt(f),
54 Error::Protoc(error) => write!(f, "protoc failed: {error}"),
55 Error::Field {
56 package,
57 message,
58 field,
59 text,
60 } => {
61 let dot = if package.is_empty() { "" } else { "." };
62 write!(f, "({dot}{package}.{message}.{field}) {text}")
63 }
64 Error::Message {
65 package,
66 message,
67 text,
68 } => {
69 let dot = if package.is_empty() { "" } else { "." };
70 write!(f, "({dot}{package}.{message}) {text}")
71 }
72 Error::Package { package, text } => {
73 let dot = if package.is_empty() { "" } else { "." };
74 write!(f, "({dot}{package}) {text}")
75 }
76 #[cfg(feature = "config-file")]
77 Error::ConfigFile { file_name, err } => {
78 write!(f, "Failed to parse {}: {err}", file_name.display())
79 }
80 }
81 }
82}
83
84impl std::error::Error for Error {
85 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
86 match self {
87 Error::Io(error) => Some(error),
88 #[cfg(feature = "config-file")]
89 Error::ConfigFile { err, .. } => Some(err),
90 Error::Field { .. }
91 | Error::Message { .. }
92 | Error::Package { .. }
93 | Error::Protoc(_) => None,
94 }
95 }
96}
97
98impl From<io::Error> for Error {
99 fn from(err: io::Error) -> Self {
100 Self::Io(err)
101 }
102}
103
104pub(crate) fn field_error(
105 pkg: &str,
106 msg_name: &str,
107 field_name: &str,
108 err_text: impl Display,
109) -> Error {
110 Error::Field {
111 package: pkg.to_owned(),
112 message: msg_name.to_owned(),
113 field: field_name.to_owned(),
114 text: err_text.to_string(),
115 }
116}
117
118pub(crate) fn msg_error(pkg: &str, msg_name: &str, err_text: impl Display) -> Error {
119 Error::Message {
120 package: pkg.to_owned(),
121 message: msg_name.to_owned(),
122 text: err_text.to_string(),
123 }
124}
125
126pub(crate) fn pkg_error(pkg: &str, err_text: impl Display) -> Error {
127 Error::Package {
128 package: pkg.to_owned(),
129 text: err_text.to_string(),
130 }
131}