Skip to content

Commit

Permalink
feat: fix
Browse files Browse the repository at this point in the history
  • Loading branch information
TroyKomodo committed Jul 8, 2023
1 parent 9d068d3 commit 1d53d59
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 83 deletions.
8 changes: 6 additions & 2 deletions common/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use anyhow::Result;

use crate::logging;
use config::KeyGraph;

#[derive(Debug, Clone, Default, PartialEq, config::Config, serde::Deserialize)]
#[serde(default)]
Expand All @@ -27,10 +26,15 @@ pub struct LoggingConfig {
pub level: String,

/// What logging mode we should use
#[config(tree = "KeyTree::String")]
pub mode: logging::Mode,
}

impl ::config::Config for logging::Mode {
fn graph() -> &'static ::config::KeyGraph {
&::config::KeyGraph::String
}
}

impl Default for LoggingConfig {
fn default() -> Self {
Self {
Expand Down
2 changes: 1 addition & 1 deletion config/config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ serde_yaml = "0"
toml = "0"
clap = { version = "4", features = ["cargo", "string"] }
convert_case = "0"
serde = { version = "1", features = ["derive"] }
serde = { version = "1", features = ["derive", "rc"] }
tracing = { version = "0" }
serde_ignored = "0"
serde-value = "0"
Expand Down
9 changes: 2 additions & 7 deletions config/config/example/derive.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
//! Run with: `cargo run --example derive`
//! Look at the generated code with: `cargo expand --example derive`

use std::collections::HashMap;

use config::{sources, ConfigBuilder, ConfigError};

type TypeAlias = bool;
Expand All @@ -12,17 +10,14 @@ type TypeAlias = bool;
struct AppConfig {
enabled: TypeAlias,
logging: LoggingConfig,
optional: Option<LoggingConfig>,
#[config(cli(skip), env(skip))]
map: HashMap<String, LoggingConfig>,
}

#[derive(config::Config, Debug, PartialEq, serde::Deserialize)]
#[serde(default)]
struct LoggingConfig {
level: String,
json: bool,
#[config(cli(skip), env(skip))]
#[config(cli(skip), env())]
cycle: Option<Box<LoggingConfig>>,
}

Expand All @@ -48,7 +43,7 @@ fn parse() -> Result<AppConfig, ConfigError> {
builder.add_source(sources::CliSource::new()?);
builder.add_source(sources::EnvSource::with_prefix("TEST")?);
builder.add_source(sources::FileSource::json(
br#"
br#"
{
"enabled": "on",
"optional": null,
Expand Down
14 changes: 10 additions & 4 deletions config/config/src/key.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
use std::{collections::{BTreeMap, btree_map::Entry}, fmt::Display, cell::RefCell, ptr::NonNull};
use std::{
cell::RefCell,
collections::{btree_map::Entry, BTreeMap},
fmt::Display,
ptr::NonNull,
};

#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
pub struct KeyPath(Vec<String>);
Expand Down Expand Up @@ -70,7 +75,7 @@ impl From<&str> for KeyPath {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone)]
pub enum KeyType {
String,
I8,
Expand All @@ -90,6 +95,7 @@ pub enum KeyType {
Struct(BTreeMap<String, KeyType>),
Map(Box<KeyType>, Box<KeyType>),
Seq(Box<KeyType>),
CyclicReference,
}

thread_local! {
Expand Down Expand Up @@ -190,7 +196,7 @@ impl std::fmt::Debug for KeyGraph {
Self::Struct(map) => write!(f, "Struct({:?})", map),
Self::Map(key, value) => write!(f, "Map({:?}, {:?})", key, value),
Self::Seq(key) => write!(f, "Seq({:?})", key),
Self::Ref(_) => write!(f, "Ref(<already shown>)"),
Self::Ref(_) => write!(f, "Ref(...)"),
}
}
}
Expand Down Expand Up @@ -220,7 +226,7 @@ impl KeyGraph {
KeyType::Map(Box::new(key.key_type()), Box::new(value.key_type()))
}
Self::Seq(key) => KeyType::Seq(Box::new(key.key_type())),
Self::Ref(_) => todo!("somehow work with keytypes"),
Self::Ref(_) => KeyType::CyclicReference,
}
}

Expand Down
26 changes: 14 additions & 12 deletions config/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ pub fn validate_from_graph(tree: &KeyGraph, value: Value) -> Result<Value> {
} else {
validate_from_graph(tree, value)
}
},
}
KeyGraph::Seq(tree) => {
if let Value::Seq(seq) = value {
let mut result = Vec::new();
Expand All @@ -317,9 +317,10 @@ pub fn validate_from_graph(tree: &KeyGraph, value: Value) -> Result<Value> {
Err(ConfigErrorEnum::ValidationError(format!(
"expected sequence, found {:?}",
value
)).into())
))
.into())
}
},
}
KeyGraph::Map(key_tree, value_tree) => {
if let Value::Map(map) = value {
let mut result = BTreeMap::new();
Expand All @@ -331,10 +332,10 @@ pub fn validate_from_graph(tree: &KeyGraph, value: Value) -> Result<Value> {

Ok(Value::Map(result))
} else {
Err(ConfigErrorEnum::ValidationError(format!(
"expected map, found {:?}",
value
)).into())
Err(
ConfigErrorEnum::ValidationError(format!("expected map, found {:?}", value))
.into(),
)
}
}
KeyGraph::Struct(tree) => {
Expand All @@ -348,7 +349,8 @@ pub fn validate_from_graph(tree: &KeyGraph, value: Value) -> Result<Value> {
return Err(ConfigErrorEnum::ValidationError(format!(
"expected string, found {:?}",
key
)).into());
))
.into());
};

let key_tree = if let Some(key_tree) = tree.get(&key_str) {
Expand All @@ -365,10 +367,10 @@ pub fn validate_from_graph(tree: &KeyGraph, value: Value) -> Result<Value> {

Ok(Value::Map(result))
} else {
Err(ConfigErrorEnum::ValidationError(format!(
"expected map, found {:?}",
value
)).into())
Err(
ConfigErrorEnum::ValidationError(format!("expected map, found {:?}", value))
.into(),
)
}
}
KeyGraph::Ref(tree) => validate_from_graph(tree, value),
Expand Down
35 changes: 17 additions & 18 deletions config/config/src/primitives.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{
cell::{Cell, RefCell},
collections::{BTreeSet, BinaryHeap, HashSet, LinkedList, VecDeque, BTreeMap, HashMap},
collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
marker::PhantomData,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
path::{PathBuf},
path::PathBuf,
rc::Rc,
sync::{Arc, Mutex, RwLock},
time::{Duration, SystemTime},
Expand Down Expand Up @@ -415,7 +415,11 @@ impl<C: Config + std::cmp::Ord> Config for BinaryHeap<C> {
}
}

impl<C: Config + std::hash::Hash + std::cmp::Eq, S: std::hash::BuildHasher + std::default::Default + 'static> Config for HashSet<C, S> {
impl<
C: Config + std::hash::Hash + std::cmp::Eq,
S: std::hash::BuildHasher + std::default::Default + 'static,
> Config for HashSet<C, S>
{
fn graph() -> &'static KeyGraph {
if let Some(graph) = KeyGraph::get::<Self>() {
return graph;
Expand Down Expand Up @@ -573,10 +577,7 @@ impl<K: Config + std::cmp::Ord, V: Config> Config for BTreeMap<K, V> {
return graph;
}

KeyGraph::store::<Self>(KeyGraph::Map(
K::graph(),
V::graph(),
))
KeyGraph::store::<Self>(KeyGraph::Map(K::graph(), V::graph()))
}

fn validate(value: Value) -> Result<Value> {
Expand All @@ -602,16 +603,18 @@ impl<K: Config + std::cmp::Ord, V: Config> Config for BTreeMap<K, V> {
}
}

impl<K: Config + std::hash::Hash + std::cmp::Eq, V: Config, S: std::hash::BuildHasher + std::default::Default + 'static> Config for HashMap<K, V, S> {
impl<
K: Config + std::hash::Hash + std::cmp::Eq,
V: Config,
S: std::hash::BuildHasher + std::default::Default + 'static,
> Config for HashMap<K, V, S>
{
fn graph() -> &'static KeyGraph {
if let Some(graph) = KeyGraph::get::<Self>() {
return graph;
}

KeyGraph::store::<Self>(KeyGraph::Map(
K::graph(),
V::graph(),
))
KeyGraph::store::<Self>(KeyGraph::Map(K::graph(), V::graph()))
}

fn validate(value: Value) -> Result<Value> {
Expand Down Expand Up @@ -909,10 +912,6 @@ macro_rules! impl_slice {
}

impl_slice!(
0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17,
18, 19, 20, 21, 22,
23, 24, 25, 26, 27,
28, 29, 30, 31, 32
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32
);
24 changes: 12 additions & 12 deletions config/config/src/sources/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use clap::{command, Arg, ArgAction, ArgMatches, Command};
use convert_case::{Case, Casing};

use crate::{
Config, ConfigError, ConfigErrorEnum, ErrorSource, KeyPath, KeyGraph, Result, Source, Value,
Config, ConfigError, ConfigErrorEnum, ErrorSource, KeyGraph, KeyPath, Result, Source, Value,
};

use super::utils;
Expand Down Expand Up @@ -177,13 +177,13 @@ fn extend_cmd(
ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type()))
.with_path(path.clone()),
)
},
}
KeyGraph::Ref(_) => {
return Err(
ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type()))
.with_path(path.clone()),
)
},
}
})
}

Expand Down Expand Up @@ -237,7 +237,13 @@ pub fn generate_command<C: Config>() -> Result<Command> {
}
};

let (arg, mut command) = extend_cmd(command, &KeyGraph::Struct(map.clone()), None, &KeyPath::new(), false)?;
let (arg, mut command) = extend_cmd(
command,
&KeyGraph::Struct(map.clone()),
None,
&KeyPath::new(),
false,
)?;

if let Some(arg) = arg {
command = command.arg(arg);
Expand Down Expand Up @@ -483,16 +489,10 @@ fn matches_to_value(
}
}
KeyGraph::Map(_, _) => {
Err(
ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type()))
.with_path(path),
)
Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type())).with_path(path))
}
KeyGraph::Ref(_) => {
Err(
ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type()))
.with_path(path),
)
Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type())).with_path(path))
}
}
}
Expand Down
44 changes: 29 additions & 15 deletions config/config/src/sources/env.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{collections::BTreeMap, marker::PhantomData};

use crate::{
Config, ConfigError, ConfigErrorEnum, ErrorSource, KeyPath, KeyGraph, KeyType, Result, Source,
Config, ConfigError, ConfigErrorEnum, ErrorSource, KeyGraph, KeyPath, KeyType, Result, Source,
Value,
};

Expand Down Expand Up @@ -34,7 +34,18 @@ impl<C: Config> EnvSource<C> {
false,
false,
)
.map_err(|e| e.with_source(ErrorSource::Env))?
.map_err(|e| {
let e = e.with_source(ErrorSource::Env);
if prefix.is_some() {
if let Some(path) = e.path().cloned() {
e.with_path(path.drop_root())
} else {
e
}
} else {
e
}
})?
.unwrap_or(Value::Option(None)),
})
}
Expand Down Expand Up @@ -96,15 +107,17 @@ fn extract_keys(
return None;
}

Some(extract_keys(
key.tree(),
prefix,
path.push_child(child_path),
joiner,
false,
false,
Some(
extract_keys(
key.tree(),
prefix,
path.push_child(child_path),
joiner,
false,
false,
)
.map(|value| value.map(|value| (Value::String(child_path.clone()), value))),
)
.map(|value| value.map(|value| (Value::String(child_path.clone()), value))))
})
.collect::<Result<Vec<_>>>()?
.into_iter()
Expand Down Expand Up @@ -136,12 +149,13 @@ fn extract_keys(
}

extract_keys(tree, prefix, path, joiner, true, false)
},
}
KeyGraph::Map(_, _) => {
Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type()))
.with_path(path))
Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type())).with_path(path))
}
KeyGraph::Ref(_) => {
Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type())).with_path(path))
}
KeyGraph::Ref(_) => Err(ConfigError::new(ConfigErrorEnum::UnsupportedType(tree.key_type())).with_path(path)),
}
}

Expand All @@ -168,6 +182,6 @@ fn parse_to_value(key_type: KeyType, s: &str) -> Result<Value> {

impl<C: Config> Source<C> for EnvSource<C> {
fn get_key(&self, path: &KeyPath) -> Result<Option<Value>> {
utils::get_key(&self.value, path).map_err(|e| e.with_source(ErrorSource::Cli))
utils::get_key(&self.value, path).map_err(|e| e.with_source(ErrorSource::Env))
}
}
Loading

0 comments on commit 1d53d59

Please sign in to comment.