#[cfg(feature = "embed-configs")]
use rust_embed::RustEmbed;
#[cfg(feature = "embed-configs")]
use std::borrow::Borrow;
use std::{collections::HashMap, path::Path};
use super::ConfigEntry;
use crate::util::Util;
#[cfg(feature = "embed-configs")]
#[derive(RustEmbed)]
#[folder = "ftr-site-config"]
struct EmbededConfigFiles;
pub struct ConfigCollection {
embedded_entries: HashMap<String, ConfigEntry>,
user_entries: HashMap<String, ConfigEntry>,
}
impl ConfigCollection {
pub async fn parse(directory: Option<&Path>) -> Self {
let mut user_entries = HashMap::new();
#[cfg(feature = "embed-configs")]
let mut embedded_entries = HashMap::new();
#[cfg(not(feature = "embed-configs"))]
let embedded_entries = HashMap::new();
#[cfg(feature = "embed-configs")]
for (file_name, entry) in EmbededConfigFiles::iter()
.filter_map(|file_name| EmbededConfigFiles::get(&file_name).map(|e| (file_name, e)))
{
let entry = match ConfigEntry::parse_data(entry.data).await {
Ok(entry) => entry,
Err(error) => {
tracing::error!(%error, "Parse config data");
continue;
}
};
let file_name: &str = file_name.borrow();
embedded_entries.insert(file_name.to_owned(), entry);
}
if let Some(directory) = directory {
if let Err(error) = std::fs::DirBuilder::new().recursive(true).create(directory) {
tracing::warn!(
?directory,
%error,
"Failed to create user config directory",
);
}
if let Ok(mut dir) = tokio::fs::read_dir(directory).await {
while let Ok(Some(entry)) = dir.next_entry().await {
if Util::check_extension(&entry, "txt")
&& let Ok(config) = ConfigEntry::parse_path(&entry.path()).await
{
let file_name = entry.file_name().to_string_lossy().into_owned();
user_entries.insert(file_name, config);
}
}
}
}
Self {
embedded_entries,
user_entries,
}
}
pub fn get(&self, key: &str) -> Option<&ConfigEntry> {
if let Some(user_entry) = self.user_entries.get(key) {
Some(user_entry)
} else {
self.embedded_entries.get(key)
}
}
}
#[cfg(test)]
mod tests {
use super::ConfigCollection;
use std::path::Path;
#[tokio::test]
async fn read_dir() {
let path = Path::new("~/.local/share/news-flash/ftr-site-config");
let _collection = ConfigCollection::parse(Some(path)).await;
}
}