99 lines
3.3 KiB
Rust
99 lines
3.3 KiB
Rust
//! `config validate` subcommand
|
|
|
|
use crate::{
|
|
command::config::{current_revision, RevisionCheckError},
|
|
config::{client, server, CLIENT_CONFIG_PATH, SERVER_CONFIG_PATH},
|
|
};
|
|
use color_print::cprintln;
|
|
use enum_iterator::Sequence;
|
|
use std::{fs, io::Read};
|
|
use validator::Validate;
|
|
|
|
/// Errors that can happen in `config validate` subcommand
|
|
#[derive(thiserror::Error, Debug)]
|
|
pub(crate) enum ValidationError {
|
|
#[error(transparent)]
|
|
ReadFile(#[from] std::io::Error),
|
|
#[error(transparent)]
|
|
UnknownRevision(#[from] RevisionCheckError),
|
|
#[error("config files are not the latest revision")]
|
|
OutOfDate,
|
|
#[error("invalid config file")]
|
|
InvalidConfig,
|
|
}
|
|
|
|
#[derive(thiserror::Error, Debug)]
|
|
enum ReadError {
|
|
#[error(transparent)]
|
|
ReadFile(#[from] std::io::Error),
|
|
#[error("the config file is not written in the correct format")]
|
|
InvalidFormat(#[from] toml::de::Error),
|
|
}
|
|
|
|
pub(super) fn run() -> Result<(), ValidationError> {
|
|
if current_revision()?.next().is_some() {
|
|
cprintln!("Please first run `<bold>fishctl config update</>` to update your config files.");
|
|
return Err(ValidationError::OutOfDate);
|
|
}
|
|
|
|
let server_validation_result = match read_server_toml() {
|
|
Ok(config) => config.validate().map_err(|err| {
|
|
cprintln!("<r!><bold>config/server.toml is invalid.</></>\n{}", err);
|
|
ValidationError::InvalidConfig
|
|
}),
|
|
Err(ReadError::InvalidFormat(err)) => {
|
|
cprintln!("<r!><bold>config/server.toml is invalid.</></>\n{}", err);
|
|
Err(ValidationError::InvalidConfig)
|
|
}
|
|
Err(ReadError::ReadFile(err)) => Err(ValidationError::ReadFile(err)),
|
|
};
|
|
|
|
let client_validation_result = match read_client_toml() {
|
|
Ok(config) => config.validate().map_err(|err| {
|
|
cprintln!(
|
|
"<r!><bold>{} is invalid.</></>\n{}",
|
|
CLIENT_CONFIG_PATH,
|
|
err
|
|
);
|
|
ValidationError::InvalidConfig
|
|
}),
|
|
Err(ReadError::InvalidFormat(err)) => {
|
|
cprintln!(
|
|
"<r!><bold>{} is invalid.</></>\n{}",
|
|
CLIENT_CONFIG_PATH,
|
|
err
|
|
);
|
|
Err(ValidationError::InvalidConfig)
|
|
}
|
|
Err(ReadError::ReadFile(err)) => Err(ValidationError::ReadFile(err)),
|
|
};
|
|
|
|
if server_validation_result.is_ok() && client_validation_result.is_ok() {
|
|
cprintln!(
|
|
"<g!><bold>{} and {} are valid!</></>",
|
|
SERVER_CONFIG_PATH,
|
|
CLIENT_CONFIG_PATH
|
|
);
|
|
cprintln!("<bold>Note:</> This command only checks the format of the config files, and its result does not guarantee the correctness of the value.");
|
|
}
|
|
|
|
server_validation_result.and(client_validation_result)
|
|
}
|
|
|
|
fn read_server_toml() -> Result<server::Config, ReadError> {
|
|
let mut file = fs::File::open(SERVER_CONFIG_PATH)?;
|
|
|
|
let mut buffer = String::new();
|
|
file.read_to_string(&mut buffer)?;
|
|
|
|
toml::from_str(&buffer).map_err(ReadError::InvalidFormat)
|
|
}
|
|
|
|
fn read_client_toml() -> Result<client::Config, ReadError> {
|
|
let mut file = fs::File::open(CLIENT_CONFIG_PATH)?;
|
|
|
|
let mut buffer = String::new();
|
|
file.read_to_string(&mut buffer)?;
|
|
|
|
toml::from_str(&buffer).map_err(ReadError::InvalidFormat)
|
|
}
|