use color_eyre::eyre;
use serde::{Serialize, Deserialize};
const CONFIG_DIR: &str = ".config/stama";
const FILENAME: &str = "salloc_list.toml";
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct SallocList<T> {
pub entries: Vec<T>,
}
impl<T: Serialize> SallocList<T> {
pub fn new() -> SallocList<T> {
SallocList {
entries: Vec::new(),
}
}
pub fn push(&mut self, item: T) {
self.entries.push(item);
}
pub fn get(&self, index: usize) -> eyre::Result<&T> {
let entry = self.entries.get(index)
.ok_or_else(|| eyre::eyre!("Index out of bounds."))?;
Ok(entry)
}
pub fn get_mut(&mut self, index: usize) -> eyre::Result<&mut T> {
let entry = self.entries.get_mut(index)
.ok_or_else(|| eyre::eyre!("Index out of bounds."))?;
Ok(entry)
}
pub fn set_list(&mut self, list: Vec<T>) {
self.entries = list;
}
pub fn len(&self) -> usize {
self.entries.len()
}
pub fn save(&self, filename: Option<&str>) -> eyre::Result<()> {
let home = std::env::var("HOME")?;
let config_dir = format!("{}/{}", home, CONFIG_DIR);
std::fs::create_dir_all(&config_dir)?;
let file = match filename {
Some(name) => format!("{}/{}", config_dir, name),
None => format!("{}/{}", config_dir, FILENAME),
};
let toml_str = toml::to_string(&self)?;
std::fs::write(file, toml_str)?;
Ok(())
}
pub fn load(filename: Option<&str>) -> eyre::Result<SallocList<T>>
where for<'de> T: Deserialize<'de> {
let home = std::env::var("HOME")?;
let file = match filename {
Some(name) => format!("{}/{}/{}", home, CONFIG_DIR, name),
None => format!("{}/{}/{}", home, CONFIG_DIR, FILENAME),
};
if !std::path::Path::new(&file).exists() {
return Ok(SallocList::new());
}
let toml_str = std::fs::read_to_string(file)?;
let list: SallocList<T> = toml::from_str(&toml_str)?;
Ok(list)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::menus::salloc::salloc_entry::SallocEntry;
#[test]
fn test_new() {
let list: SallocList<SallocEntry> = SallocList::new();
assert_eq!(list.len(), 0);
}
#[test]
fn test_push() {
let mut list: SallocList<SallocEntry> = SallocList::new();
let entry = SallocEntry::new();
list.push(entry);
assert_eq!(list.len(), 1);
}
#[test]
fn test_get() {
let mut list: SallocList<SallocEntry> = SallocList::new();
let entry = SallocEntry::new();
list.push(entry);
let entry_ref: &SallocEntry = list.get(0).unwrap();
assert_eq!(entry_ref.preset_name, "new");
}
#[test]
fn test_save() {
let mut list: SallocList<SallocEntry> = SallocList::new();
let entry = SallocEntry::new();
list.push(entry);
list.save(Some("test_save.toml")).unwrap();
let home = std::env::var("HOME").unwrap();
let file = format!("{}/{}/test_save.toml", home, CONFIG_DIR);
assert!(std::path::Path::new(&file).exists());
}
#[test]
fn test_load() {
let mut list: SallocList<SallocEntry> = SallocList::new();
let mut entry = SallocEntry::new();
entry.preset_name = "test".to_string();
list.push(entry);
list.save(Some("test_load.toml")).unwrap();
let loaded_list: SallocList<SallocEntry> =
SallocList::load(Some("test_load.toml")).unwrap();
assert_eq!(loaded_list.len(), 1);
let entry = loaded_list.get(0).unwrap();
assert_eq!(entry.preset_name, "test");
}
}