use std::collections::HashSet;
use super::tree::StrNode;
use crate::{Category, Source};
pub struct KeyValueSource {
name: String,
entries: Vec<(String, String)>,
list_keys: HashSet<String>,
json_values: bool,
}
impl KeyValueSource {
pub fn new<I, K, V>(name: impl Into<String>, entries: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
K: Into<String>,
V: Into<String>,
{
Self {
name: name.into(),
entries: entries
.into_iter()
.map(|(k, v)| (k.into(), v.into()))
.collect(),
list_keys: HashSet::new(),
json_values: false,
}
}
#[must_use]
pub fn with_list_keys<I, S>(mut self, keys: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.list_keys.extend(keys.into_iter().map(Into::into));
self
}
#[cfg(feature = "json")]
#[must_use]
pub fn with_json_values(mut self) -> Self {
self.json_values = true;
self
}
}
impl Source for KeyValueSource {
fn name(&self) -> &str {
&self.name
}
fn category(&self) -> Category {
Category::Database
}
fn deserialize(
&self,
seed: &mut dyn for<'de> FnMut(
&mut dyn erased_serde::Deserializer<'de>,
) -> Result<(), erased_serde::Error>,
) -> Result<(), erased_serde::Error> {
let entries = self
.entries
.iter()
.map(|(key, value)| (key.split('.').map(str::to_string).collect(), value.clone()))
.collect();
StrNode::from_entries(entries, &self.list_keys, self.json_values).feed(seed)
}
}