mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-19 19:08:08 +00:00
config: add basic abstraction over &str, [&str], and &ConfigNamePathBuf
We usually look up config objects with a static name, but commands like "jj config get" has to parse a user input as a config key. We could consolidate the name type to &ConfigNamePathBuf, but it would be inconvenient if all callers had to do config.get(&"..".parse()?). It's also undesirable to pass a raw user input in to .get() as a string. I originally considered making it support fallible conversion, but doing that would complicate error handling path. Not all functions should return an error. It's better to do fallible parsing at the call sites instead. A string config name is parsed into a temporary ConfigNamePathBuf object. If the allocation cost matters, the output path type can be abstracted.
This commit is contained in:
parent
5946ef3880
commit
8557a0ff0a
1 changed files with 68 additions and 0 deletions
|
@ -14,6 +14,7 @@
|
|||
|
||||
//! Configuration store helpers.
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::ops::Range;
|
||||
|
@ -138,6 +139,73 @@ impl fmt::Display for ConfigNamePathBuf {
|
|||
}
|
||||
}
|
||||
|
||||
/// Value that can be converted to a dotted config name path.
|
||||
///
|
||||
/// This is an abstraction to specify a config name path in either a string or a
|
||||
/// parsed form. It's similar to `Into<T>`, but the output type `T` is
|
||||
/// constrained by the source type.
|
||||
pub trait ToConfigNamePath: Sized {
|
||||
/// Path type to be converted from `Self`.
|
||||
type Output: Borrow<ConfigNamePathBuf>;
|
||||
|
||||
/// Converts this object into a dotted config name path.
|
||||
fn into_name_path(self) -> Self::Output;
|
||||
}
|
||||
|
||||
impl ToConfigNamePath for ConfigNamePathBuf {
|
||||
type Output = Self;
|
||||
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ToConfigNamePath for &ConfigNamePathBuf {
|
||||
type Output = Self;
|
||||
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ToConfigNamePath for &'static str {
|
||||
// This can be changed to ConfigNamePathStr(str) if allocation cost matters.
|
||||
type Output = ConfigNamePathBuf;
|
||||
|
||||
/// Parses this string into a dotted config name path.
|
||||
///
|
||||
/// The string must be a valid TOML dotted key. A static str is required to
|
||||
/// prevent API misuse.
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self.parse()
|
||||
.expect("valid TOML dotted key must be provided")
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> ToConfigNamePath for [&str; N] {
|
||||
type Output = ConfigNamePathBuf;
|
||||
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self.into_iter().collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> ToConfigNamePath for &[&str; N] {
|
||||
type Output = ConfigNamePathBuf;
|
||||
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self.as_slice().into_name_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToConfigNamePath for &[&str] {
|
||||
type Output = ConfigNamePathBuf;
|
||||
|
||||
fn into_name_path(self) -> Self::Output {
|
||||
self.iter().copied().collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Source of configuration variables in order of precedence.
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum ConfigSource {
|
||||
|
|
Loading…
Reference in a new issue