use color_eyre::eyre;
use serde::{Serialize, Deserialize};
#[derive(Debug, PartialEq, Serialize, Deserialize, Default)]
pub struct TomlList<T> {
pub entry: Vec<T>,
}
impl<T: Serialize> TomlList<T> {
pub fn new() -> TomlList<T> {
TomlList {
entry: Vec::new(),
}
}
pub fn push(&mut self, item: T) {
self.entry.push(item);
}
pub fn get(&self, index: usize) -> eyre::Result<&T> {
let entry = self.entry.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.entry.get_mut(index)
.ok_or_else(|| eyre::eyre!("Index out of bounds."))?;
Ok(entry)
}
pub fn set_list(&mut self, list: Vec<T>) {
self.entry = list;
}
pub fn len(&self) -> usize {
self.entry.len()
}
pub fn save(&self, filename: &str) -> eyre::Result<()> {
let home = std::env::var("HOME")?;
let config_dir = format!("{}/.config/code-remote", home);
std::fs::create_dir_all(&config_dir)?;
let file = format!("{}/{}.toml", config_dir, filename);
let toml_str = toml::to_string(&self)?;
std::fs::write(file, toml_str)?;
Ok(())
}
pub fn load(filename: &str) -> eyre::Result<TomlList<T>>
where for<'de> T: Deserialize<'de> {
let home = std::env::var("HOME")?;
let file = format!("{}/.config/code-remote/{}.toml", home, filename);
if !std::path::Path::new(&file).exists() {
return Ok(TomlList::new());
}
let toml_str = std::fs::read_to_string(file)?;
let list: TomlList<T> = toml::from_str(&toml_str)?;
Ok(list)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::menus::cluster;
#[test]
fn test_new() {
let list: TomlList<cluster::Cluster> = TomlList::new();
assert_eq!(list.len(), 0);
}
#[test]
fn test_push() {
let mut list: TomlList<cluster::Cluster> = TomlList::new();
let cluster = cluster::Cluster::new("test", "test", "test", "test");
list.push(cluster);
assert_eq!(list.len(), 1);
}
#[test]
fn test_get() {
let mut list: TomlList<cluster::Cluster> = TomlList::new();
let cluster = cluster::Cluster::new(
"mname", "mhost", "muser", "mid");
list.push(cluster);
let entry = list.get(0).unwrap();
assert_eq!(entry.name, "mname");
assert_eq!(entry.host, "mhost");
assert_eq!(entry.user, "muser");
assert_eq!(entry.identity_file, "mid");
}
#[test]
fn test_save() {
let mut list: TomlList<cluster::Cluster> = TomlList::new();
let cluster = cluster::Cluster::new("test", "test", "test", "test");
list.push(cluster);
list.save("test").unwrap();
let home = std::env::var("HOME").unwrap();
let file = format!("{}/.config/code-remote/test.toml", home);
assert!(std::path::Path::new(&file).exists());
}
#[test]
fn test_load() {
let mut list: TomlList<cluster::Cluster> = TomlList::new();
let cluster = cluster::Cluster::new(
"mname", "mhost", "muser", "mid");
list.push(cluster);
list.save("test").unwrap();
let loaded_list: TomlList<cluster::Cluster> = TomlList::load("test").unwrap();
assert_eq!(loaded_list.len(), 1);
let entry = loaded_list.get(0).unwrap();
assert_eq!(entry.name, "mname");
assert_eq!(entry.host, "mhost");
assert_eq!(entry.user, "muser");
assert_eq!(entry.identity_file, "mid");
}
}