#![allow(private_bounds)]
use qubit_value::multi_values::{MultiValuesFirstGetter, MultiValuesGetter};
use qubit_value::MultiValues;
use serde::de::DeserializeOwned;
use crate::config_prefix_view::ConfigPrefixView;
use crate::{utils, Config, ConfigResult, Property};
pub trait ConfigReader {
fn is_enable_variable_substitution(&self) -> bool;
fn max_substitution_depth(&self) -> usize;
fn description(&self) -> Option<&str>;
fn get_property(&self, name: &str) -> Option<&Property>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn keys(&self) -> Vec<String>;
fn contains(&self, name: &str) -> bool;
fn get<T>(&self, name: &str) -> ConfigResult<T>
where
MultiValues: MultiValuesFirstGetter<T>;
fn get_list<T>(&self, name: &str) -> ConfigResult<Vec<T>>
where
MultiValues: MultiValuesGetter<T>;
#[inline]
fn get_or<T>(&self, name: &str, default: T) -> T
where
MultiValues: MultiValuesFirstGetter<T>,
{
self.get(name).unwrap_or(default)
}
fn get_optional<T>(&self, name: &str) -> ConfigResult<Option<T>>
where
MultiValues: MultiValuesFirstGetter<T>;
fn get_optional_list<T>(&self, name: &str) -> ConfigResult<Option<Vec<T>>>
where
MultiValues: MultiValuesGetter<T>;
fn contains_prefix(&self, prefix: &str) -> bool;
fn iter_prefix<'a>(
&'a self,
prefix: &'a str,
) -> Box<dyn Iterator<Item = (&'a str, &'a Property)> + 'a>;
fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (&'a str, &'a Property)> + 'a>;
fn is_null(&self, name: &str) -> bool;
fn subconfig(&self, prefix: &str, strip_prefix: bool) -> ConfigResult<Config>;
fn deserialize<T>(&self, prefix: &str) -> ConfigResult<T>
where
T: DeserializeOwned;
fn prefix_view(&self, prefix: &str) -> ConfigPrefixView<'_>;
fn get_string(&self, name: &str) -> ConfigResult<String> {
let value: String = self.get(name)?;
if self.is_enable_variable_substitution() {
utils::substitute_variables(&value, self, self.max_substitution_depth())
} else {
Ok(value)
}
}
#[inline]
fn get_string_or(&self, name: &str, default: &str) -> String {
self.get_string(name)
.unwrap_or_else(|_| default.to_string())
}
fn get_string_list(&self, name: &str) -> ConfigResult<Vec<String>> {
let values: Vec<String> = self.get_list(name)?;
if self.is_enable_variable_substitution() {
values
.into_iter()
.map(|v| utils::substitute_variables(&v, self, self.max_substitution_depth()))
.collect()
} else {
Ok(values)
}
}
#[inline]
fn get_string_list_or(&self, name: &str, default: &[&str]) -> Vec<String> {
self.get_string_list(name)
.unwrap_or_else(|_| default.iter().map(|s| s.to_string()).collect())
}
#[inline]
fn get_optional_string(&self, name: &str) -> ConfigResult<Option<String>> {
match self.get_property(name) {
None => Ok(None),
Some(prop) if prop.is_empty() => Ok(None),
Some(_) => self.get_string(name).map(Some),
}
}
#[inline]
fn get_optional_string_list(&self, name: &str) -> ConfigResult<Option<Vec<String>>> {
match self.get_property(name) {
None => Ok(None),
Some(prop) if prop.is_empty() => Ok(None),
Some(_) => self.get_string_list(name).map(Some),
}
}
}