Skip to content

Commit 72af712

Browse files
committed
refactor(rcfile): use thiserror, improve names
1 parent cf20c9c commit 72af712

6 files changed

Lines changed: 45 additions & 77 deletions

File tree

src/rcfile/discovery.rs

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use {
22
crate::{
33
cli::Cli,
44
rcfile::{
5-
error::ConfigError, javascript::try_from_js_candidates, json::try_from_json_candidates,
6-
package_json::try_from_package_json_config_property, yaml::try_from_yaml_candidates, Rcfile,
5+
javascript::try_from_js_candidates, json::try_from_json_candidates, package_json::try_from_package_json_config_property,
6+
yaml::try_from_yaml_candidates, Rcfile,
77
},
88
},
99
log::{debug, error},
@@ -20,43 +20,7 @@ impl Rcfile {
2020
.map(|result| match result {
2121
Ok(rcfile) => rcfile,
2222
Err(err) => {
23-
match err {
24-
ConfigError::FileReadFailed(err) => {
25-
error!("Failed to read config file: {:?}", err);
26-
}
27-
ConfigError::CommandExecutionFailed(err) => {
28-
error!("Failed to run Node.js/npx/tsx to retrieve JS/TS config file: {:?}", err);
29-
}
30-
ConfigError::ProcessFailed { stderr } => {
31-
error!("Node.js/npx/tsx process failed with stderr: {}", stderr);
32-
}
33-
ConfigError::InvalidUtf8(err) => {
34-
error!("Config file contains invalid UTF-8: {:?}", err);
35-
}
36-
ConfigError::ConfigDeserializationFailed(err) => {
37-
error!("Failed to deserialise config file: {:?}", err);
38-
}
39-
ConfigError::ImportAndRequireFailed {
40-
import_error,
41-
require_error,
42-
} => {
43-
if !import_error.is_empty() {
44-
error!("Failed to read JS/TS config file using import(): {:?}", import_error);
45-
}
46-
if !require_error.is_empty() {
47-
error!("Failed to read JS/TS config file using require(): {:?}", require_error);
48-
}
49-
}
50-
ConfigError::JsonParseFailed(err) => {
51-
error!("Failed to parse JSON in config file: {:?}", err);
52-
}
53-
ConfigError::YamlParseFailed(err) => {
54-
error!("Failed to parse YAML in config file: {:?}", err);
55-
}
56-
ConfigError::PackageJsonConfigInvalid(err) => {
57-
error!("Invalid .syncpack or .config.syncpack property defined in package.json: {:?}", err);
58-
}
59-
}
23+
error!("{}", err);
6024
exit(1);
6125
}
6226
})

src/rcfile/error.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use {serde::Deserialize, serde_json::Value};
1+
use {serde::Deserialize, serde_json::Value, thiserror::Error};
22

33
#[derive(Debug, Deserialize)]
44
#[serde(tag = "_tag")]
@@ -14,20 +14,24 @@ pub enum NodeJsResult {
1414
},
1515
}
1616

17-
#[derive(Debug)]
18-
pub enum ConfigError {
19-
// File operations
20-
FileReadFailed(std::io::Error),
21-
// JavaScript/TypeScript specific
22-
CommandExecutionFailed(std::io::Error),
17+
#[derive(Debug, Error)]
18+
pub enum RcfileError {
19+
#[error("Failed to read config file")]
20+
FileReadFailed(#[from] std::io::Error),
21+
#[error("Failed to run Node.js/npx/tsx to retrieve JS/TS config file")]
22+
NodeJsExecutionFailed(#[source] std::io::Error),
23+
#[error("Node.js/npx/tsx process failed with stderr: {stderr}")]
2324
ProcessFailed { stderr: String },
24-
InvalidUtf8(std::string::FromUtf8Error),
25-
ConfigDeserializationFailed(serde_json::Error),
26-
ImportAndRequireFailed { import_error: String, require_error: String },
27-
// JSON specific
28-
JsonParseFailed(serde_json::Error),
29-
// YAML specific
30-
YamlParseFailed(serde_yaml::Error),
31-
// Package.json specific
32-
PackageJsonConfigInvalid(serde_json::Error),
25+
#[error("Config file contains invalid UTF-8")]
26+
InvalidUtf8(#[from] std::string::FromUtf8Error),
27+
#[error("Config file failed validation")]
28+
InvalidConfig(#[from] serde_json::Error),
29+
#[error("Failed to import or require config file: {import_error} {require_error}")]
30+
JavaScriptImportFailed { import_error: String, require_error: String },
31+
#[error("Failed to parse JSON in config file")]
32+
JsonParseFailed(#[source] serde_json::Error),
33+
#[error("Failed to parse YAML in config file")]
34+
YamlParseFailed(#[from] serde_yaml::Error),
35+
#[error("Config defined as a property in package.json failed validation")]
36+
PackageJsonConfigInvalid(#[source] serde_json::Error),
3337
}

src/rcfile/javascript.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ use {
22
crate::{
33
cli::Cli,
44
rcfile::{
5-
error::{ConfigError, NodeJsResult},
5+
error::{NodeJsResult, RcfileError},
66
Rcfile,
77
},
88
},
99
log::debug,
1010
std::{path::Path, process::Command},
1111
};
1212

13-
pub fn from_javascript_path(file_path: &Path) -> Result<Rcfile, ConfigError> {
13+
pub fn from_javascript_path(file_path: &Path) -> Result<Rcfile, RcfileError> {
1414
let escaped_file_path_for_nodejs = file_path.to_string_lossy().replace('\\', "\\\\");
1515
let nodejs_script = format!(
1616
r#"
@@ -67,34 +67,34 @@ pub fn from_javascript_path(file_path: &Path) -> Result<Rcfile, ConfigError> {
6767
.args(["tsx", "-e", &nodejs_script])
6868
.current_dir(file_path.parent().unwrap_or_else(|| Path::new(".")))
6969
.output()
70-
.map_err(ConfigError::CommandExecutionFailed)
70+
.map_err(RcfileError::NodeJsExecutionFailed)
7171
.and_then(|output| {
7272
if output.status.success() {
7373
Ok(output.stdout)
7474
} else {
75-
Err(ConfigError::ProcessFailed {
75+
Err(RcfileError::ProcessFailed {
7676
stderr: String::from_utf8_lossy(&output.stderr).to_string(),
7777
})
7878
}
7979
})
80-
.and_then(|stdout| String::from_utf8(stdout).map_err(ConfigError::InvalidUtf8))
80+
.and_then(|stdout| String::from_utf8(stdout).map_err(RcfileError::InvalidUtf8))
8181
.inspect(|json_str| {
8282
debug!("Raw output from {:?}: {}", file_path, json_str.trim());
8383
})
84-
.and_then(|json_str| serde_json::from_str::<NodeJsResult>(&json_str).map_err(ConfigError::JsonParseFailed))
84+
.and_then(|json_str| serde_json::from_str::<NodeJsResult>(&json_str).map_err(RcfileError::JsonParseFailed))
8585
.and_then(|response| match response {
86-
NodeJsResult::Success { value } => serde_json::from_value(value).map_err(ConfigError::ConfigDeserializationFailed),
86+
NodeJsResult::Success { value } => serde_json::from_value(value).map_err(RcfileError::InvalidConfig),
8787
NodeJsResult::Error {
8888
import_error,
8989
require_error,
90-
} => Err(ConfigError::ImportAndRequireFailed {
90+
} => Err(RcfileError::JavaScriptImportFailed {
9191
import_error,
9292
require_error,
9393
}),
9494
})
9595
}
9696

97-
pub fn try_from_js_candidates(cli: &Cli) -> Option<Result<Rcfile, ConfigError>> {
97+
pub fn try_from_js_candidates(cli: &Cli) -> Option<Result<Rcfile, RcfileError>> {
9898
let candidates = vec![
9999
".syncpackrc.js",
100100
".syncpackrc.ts",

src/rcfile/json.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
use {
22
crate::{
33
cli::Cli,
4-
rcfile::{error::ConfigError, Rcfile},
4+
rcfile::{error::RcfileError, Rcfile},
55
},
66
log::debug,
77
std::{fs, path::Path},
88
};
99

10-
pub fn from_json_path(file_path: &Path) -> Result<Rcfile, ConfigError> {
10+
pub fn from_json_path(file_path: &Path) -> Result<Rcfile, RcfileError> {
1111
fs::read_to_string(file_path)
12-
.map_err(ConfigError::FileReadFailed)
13-
.and_then(|contents| serde_json::from_str::<Rcfile>(&contents).map_err(ConfigError::JsonParseFailed))
12+
.map_err(RcfileError::FileReadFailed)
13+
.and_then(|contents| serde_json::from_str::<Rcfile>(&contents).map_err(RcfileError::JsonParseFailed))
1414
}
1515

16-
pub fn try_from_json_candidates(cli: &Cli) -> Option<Result<Rcfile, ConfigError>> {
16+
pub fn try_from_json_candidates(cli: &Cli) -> Option<Result<Rcfile, RcfileError>> {
1717
let candidates = vec![".syncpackrc", ".syncpackrc.json"];
1818
for candidate in candidates {
1919
let config_path = cli.cwd.join(candidate);

src/rcfile/package_json.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use {
22
crate::{
33
cli::Cli,
4-
rcfile::{error::ConfigError, Rcfile},
4+
rcfile::{error::RcfileError, Rcfile},
55
},
66
log::debug,
77
serde_json::Value,
88
std::fs,
99
};
1010

11-
pub fn try_from_package_json_config_property(cli: &Cli) -> Option<Result<Rcfile, ConfigError>> {
11+
pub fn try_from_package_json_config_property(cli: &Cli) -> Option<Result<Rcfile, RcfileError>> {
1212
let package_json_path = cli.cwd.join("package.json");
1313
package_json_path
1414
.exists()
@@ -26,6 +26,6 @@ pub fn try_from_package_json_config_property(cli: &Cli) -> Option<Result<Rcfile,
2626
.inspect(|_| debug!("Found .config.syncpack property in package.json"))
2727
.map(|config| config.take())
2828
})
29-
.map(|syncpack_config| serde_json::from_value(syncpack_config).map_err(ConfigError::PackageJsonConfigInvalid))
29+
.map(|syncpack_config| serde_json::from_value(syncpack_config).map_err(RcfileError::PackageJsonConfigInvalid))
3030
})
3131
}

src/rcfile/yaml.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
use {
22
crate::{
33
cli::Cli,
4-
rcfile::{error::ConfigError, Rcfile},
4+
rcfile::{error::RcfileError, Rcfile},
55
},
66
log::debug,
77
std::{fs, path::Path},
88
};
99

10-
pub fn from_yaml_path(file_path: &Path) -> Result<Rcfile, ConfigError> {
10+
pub fn from_yaml_path(file_path: &Path) -> Result<Rcfile, RcfileError> {
1111
fs::read_to_string(file_path)
12-
.map_err(ConfigError::FileReadFailed)
13-
.and_then(|contents| serde_yaml::from_str::<Rcfile>(&contents).map_err(ConfigError::YamlParseFailed))
12+
.map_err(RcfileError::FileReadFailed)
13+
.and_then(|contents| serde_yaml::from_str::<Rcfile>(&contents).map_err(RcfileError::YamlParseFailed))
1414
}
1515

16-
pub fn try_from_yaml_candidates(cli: &Cli) -> Option<Result<Rcfile, ConfigError>> {
16+
pub fn try_from_yaml_candidates(cli: &Cli) -> Option<Result<Rcfile, RcfileError>> {
1717
let candidates = vec![".syncpackrc.yaml", ".syncpackrc.yml"];
1818
for candidate in candidates {
1919
let config_path = cli.cwd.join(candidate);

0 commit comments

Comments
 (0)