117 lines
3.0 KiB
Rust
117 lines
3.0 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::slice::Iter;
|
|
|
|
use crate::utils::err::Res;
|
|
|
|
enum FileFormat { Json, Yaml }
|
|
|
|
pub struct EntityManager<E> {
|
|
file_path: PathBuf,
|
|
list: Vec<E>,
|
|
}
|
|
|
|
impl<E> EntityManager<E>
|
|
where
|
|
E: serde::Serialize + serde::de::DeserializeOwned + Eq + Clone,
|
|
{
|
|
/// Open entity
|
|
pub fn open_or_create<A: AsRef<Path>>(path: A) -> Res<Self> {
|
|
if !path.as_ref().is_file() {
|
|
log::warn!("Entities at {:?} does not point to a file, creating a new empty entity container...", path.as_ref());
|
|
return Ok(Self {
|
|
file_path: path.as_ref().to_path_buf(),
|
|
list: vec![],
|
|
});
|
|
}
|
|
|
|
log::info!("Open existing entity file {:?}", path.as_ref());
|
|
let file_content = std::fs::read_to_string(path.as_ref())?;
|
|
Ok(Self {
|
|
file_path: path.as_ref().to_path_buf(),
|
|
list: match Self::file_format(path.as_ref()) {
|
|
FileFormat::Json => serde_json::from_str(&file_content)?,
|
|
FileFormat::Yaml => serde_yaml::from_str(&file_content)?
|
|
},
|
|
})
|
|
}
|
|
|
|
/// Save the list
|
|
fn save(&self) -> Res {
|
|
Ok(std::fs::write(
|
|
&self.file_path,
|
|
match Self::file_format(self.file_path.as_ref()) {
|
|
FileFormat::Json => serde_json::to_string(&self.list)?,
|
|
FileFormat::Yaml => serde_yaml::to_string(&self.list)?,
|
|
},
|
|
)?)
|
|
}
|
|
|
|
fn file_format(p: &Path) -> FileFormat {
|
|
match p.to_string_lossy().ends_with(".json") {
|
|
true => FileFormat::Json,
|
|
false => FileFormat::Yaml
|
|
}
|
|
}
|
|
|
|
/// Get the number of entries in the list
|
|
pub fn len(&self) -> usize {
|
|
self.list.len()
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.len() == 0
|
|
}
|
|
|
|
/// Insert a new element in the list
|
|
pub fn insert(&mut self, el: E) -> Res {
|
|
self.list.push(el);
|
|
self.save()
|
|
}
|
|
|
|
/// Replace entries in the list that matches a criteria
|
|
pub fn replace_entries<F>(&mut self, filter: F, el: &E) -> Res
|
|
where
|
|
F: Fn(&E) -> bool,
|
|
{
|
|
for i in 0..self.list.len() {
|
|
if filter(&self.list[i]) {
|
|
self.list[i] = el.clone();
|
|
}
|
|
}
|
|
|
|
self.save()
|
|
}
|
|
|
|
/// Iterate over the entries of this entity manager
|
|
pub fn iter(&self) -> Iter<'_, E> {
|
|
self.list.iter()
|
|
}
|
|
|
|
/// Get a cloned list of entries
|
|
pub fn cloned(&self) -> Vec<E> {
|
|
self.list.clone()
|
|
}
|
|
|
|
pub fn update_or_push(&mut self, entry: E) -> Res {
|
|
let mut found = false;
|
|
for i in &mut self.list {
|
|
if i == &entry {
|
|
*i = entry.clone();
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
self.list.push(entry);
|
|
}
|
|
|
|
self.save()
|
|
}
|
|
|
|
pub fn remove(&mut self, entry: &E) -> Res {
|
|
self.list.retain(|x| x != entry);
|
|
self.save()
|
|
}
|
|
}
|