-
Notifications
You must be signed in to change notification settings - Fork 277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance configuration errors #4299
Comments
|
Alternative designSo far, I have come up with the following design. Imagine we have a simplified configuration, having the following structure: #[derive(Deserialize, Debug)]
pub struct Root {
pub chain_id: String,
pub torii: Torii,
pub kura: Kura,
pub telemetry: Telemetry,
pub logger: Logger,
}
#[derive(Deserialize, Debug)]
pub struct Torii {
pub address: WithOrigin<SocketAddr>,
pub max_content_len: u64,
}
#[derive(Deserialize, Debug)]
pub struct Kura {
pub store_dir: WithOrigin<PathBuf>,
pub debug_force: bool,
}
#[derive(Deserialize, Debug)]
pub struct Telemetry {
pub out_file: Option<WithOrigin<PathBuf>>,
}
#[derive(Deserialize, Debug)]
pub struct Logger {
pub level: LogLevel,
}
#[derive(Deserialize, Debug, Default)]
pub enum LogLevel {
Debug,
#[default]
Info,
Warning,
Error,
} The only new thing here so far is pub enum ParameterOrigin {
File { path: PathBuf, name: String },
Env { key: String, name: String },
Default { name: String },
}
pub struct WithOrigin<T> { /* ... */ } This
The second part of my idea is to abandon impl Root {
pub fn compose(path: impl AsRef<Path>) -> Result<Self, ReadConfigError> {
let reader =
// reads the file by the path as well as a whole "extends" chain
ConfigReader::new(Some(path))?;
let (chain_id, reader) = reader
.parameter::<String, _>(["chain_id"])
.env("CHAIN_ID")
.value_required()
.finish();
let (torii_address, reader) = reader
.parameter::<SocketAddr, _>(["torii", "address"])
.env("API_ADDRESS")
.value_or_else(|| todo!())
.finish_with_origin();
let (torii_max_content_len, reader) = reader
.parameter::<u64, _>(["torii", "max_content_length"])
.value_or(1024)
.finish();
// origin needed so that we can resolve the path relative to the origin
let (kura_store_dir, reader) = reader
.parameter::<PathBuf, _>(["kura", "store_dir"])
.env("KURA_STORE_DIR")
.value_or_else(|| PathBuf::from("./storage"))
.finish_with_origin();
let (kura_debug_force, reader) = reader
.parameter::<bool, _>(["kura", "debug_force"])
.value_or(false)
.finish();
let (log_level, reader) = reader
.parameter::<LogLevel, _>(["logger", "level"])
.env("LOG_LEVEL")
.value_or_default()
.finish();
// origin needed so that we can resolve the path relative to the origin
let (telemetry_out_file, reader) = reader
.parameter::<PathBuf, _>(["telemetry", "dev", "out_file"])
.value_optional()
.finish_with_origin();
reader.finish()?;
// Done! _User_ layer of the config might be successfully composed now
Ok(Self {
chain_id: chain_id.unwrap(),
torii: Torii {
address: torii_address,
max_content_len: torii_max_content_len,
},
kura: Kura {
store_dir: kura_store_dir,
debug_force: kura_debug_force,
},
telemetry: Telemetry {
out_file: telemetry_out_file,
},
logger: Logger { level: log_level },
})
}
} With this design, there are the following things done by
Benefits:
Downsides:
What is not included here:
|
Closed by #4456 |
This might be probably solved as part of #4297.
Points:
eyre::Report
.The text was updated successfully, but these errors were encountered: