1use std::{
4 error::Error,
5 fmt::{self, Display},
6 path::PathBuf,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
13pub enum ConfigError {
14 InvalidLanguage(String),
16 MissingSource,
18 MissingFallback,
20 InvalidFallback,
22}
23
24impl Error for ConfigError {}
25
26impl Display for ConfigError {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 ConfigError::InvalidLanguage(value) => {
30 write!(f, "`{}` is not a valid language identifier", value)
31 }
32 ConfigError::MissingSource => {
33 write!(f, "at least one translations source file is required")
34 }
35 ConfigError::MissingFallback => write!(f, "a fallback language must be provided"),
36 ConfigError::InvalidFallback => write!(
37 f,
38 "no source corresponding to the fallback language was found"
39 ),
40 }
41 }
42}
43
44#[derive(Debug)]
46pub enum BuildError {
47 Config(ConfigError),
48 FileRead {
49 file: PathBuf,
50 source: std::io::Error,
51 },
52 FileWrite(std::io::Error),
53 JsonParse {
54 file: PathBuf,
55 source: tinyjson::JsonParseError,
56 },
57 Parse(ParseError),
58 Var(std::env::VarError),
59 Fmt(std::io::Error),
60}
61
62impl Error for BuildError {}
63
64impl Display for BuildError {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 match self {
67 BuildError::Config(error) => write!(f, "invalid configuration: {}", error),
68 BuildError::FileRead { file, source } => {
69 write!(f, "failed to read `{:?}`: {}", file, source)
70 }
71 BuildError::FileWrite(error) => write!(f, "failed to write output: {}", error),
72 BuildError::JsonParse { file, source } => {
73 write!(f, "failed to load {:?}: {}", file, source)
74 }
75 BuildError::Parse(error) => write!(f, "failed to parse translations: {}", error),
76 BuildError::Var(error) => write!(f, "failed to read environment variable: {}", error),
77 BuildError::Fmt(error) => write!(f, "failed to run rustfmt: {}", error),
78 }
79 }
80}
81
82impl From<ConfigError> for BuildError {
83 fn from(error: ConfigError) -> Self {
84 Self::Config(error)
85 }
86}
87
88impl From<ParseError> for BuildError {
89 fn from(error: ParseError) -> Self {
90 Self::Parse(error)
91 }
92}
93
94impl From<std::io::Error> for BuildError {
95 fn from(error: std::io::Error) -> Self {
96 Self::FileWrite(error)
97 }
98}
99
100impl From<std::env::VarError> for BuildError {
101 fn from(error: std::env::VarError) -> Self {
102 Self::Var(error)
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
108pub enum ParseError {
109 InvalidRoot,
111 InvalidValue { key: String },
113 InvalidType { key: String, expected: &'static str },
115 InvalidParameters {
117 key: String,
118 missing: Vec<String>,
119 unknown: Vec<String>,
120 },
121 InvalidLanguageId { value: String },
123}
124
125impl Error for ParseError {}
126
127impl Display for ParseError {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 match self {
130 ParseError::InvalidRoot => write!(f, "file root must be a json object"),
131 ParseError::InvalidValue { key } => write!(f, "`{}` has an invalid type", key),
132 ParseError::InvalidType { key, expected } => write!(
133 f,
134 "`{}` doesn't match previous parsed key (expected {})",
135 key, expected
136 ),
137 ParseError::InvalidParameters {
138 key,
139 missing,
140 unknown,
141 } => write!(
142 f,
143 "invalid parameters supplied to `{}` (missing: {:?}, unknown: {:?})",
144 key, missing, unknown
145 ),
146 ParseError::InvalidLanguageId { value } => write!(
147 f,
148 "`{}` is not a valid ISO 693-1 language identifier",
149 value
150 ),
151 }
152 }
153}