use std::env; use std::error::Error; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::{fs::File, path::PathBuf}; use serde::{Deserialize, Serialize}; use crate::Result; pub fn get_world_location() -> Result { match env::var("TOPAZ_WORLD") { Ok(x) => Ok(x.into()), Err(env::VarError::NotPresent) => Ok("/etc/topaz/world.toml".into()), Err(env::VarError::NotUnicode(_)) => Err("World location in env is invalid!".into()), } } #[derive(Debug, Serialize, Deserialize)] pub struct Packages { pub official: Vec, pub foreign: Vec, pub ignore: Vec, } #[derive(Debug, Serialize, Deserialize)] pub struct World { packages: Packages, } impl Packages { pub fn new() -> Packages { Packages { official: Vec::new(), foreign: Vec::new(), ignore: Vec::new(), } } } impl Packages { pub fn exclude(&self, other: &Self) -> Self { let official = self .official .iter() .filter(|x| !other.official.contains(x)) .cloned() .collect(); let foreign = self .foreign .iter() .filter(|x| !other.foreign.contains(x)) .cloned() .collect(); Packages { official, foreign, ignore: Vec::new(), } } pub fn exclude_ignored(&mut self) { self.official.retain(|x| !self.ignore.contains(x)); self.foreign.retain(|x| !self.ignore.contains(x)); } } impl World { pub fn new_empty() -> World { World { packages: Packages::new(), } } pub fn get_packages(&self) -> &Packages { &self.packages } pub fn get_mut_packages(&mut self) -> &mut Packages { &mut self.packages } pub fn load_from(world_path: PathBuf) -> Result { let mut file = File::open(world_path)?; let mut text = String::new(); file.read_to_string(&mut text)?; let world: World = toml::from_str(&text)?; Ok(world) } pub fn save(&self, world_path: Option, do_print: bool) -> Result<()> { let text = toml::to_string_pretty(self)?; if let Some(world_path) = world_path { let mut file = OpenOptions::new() .write(true) .create(true) .truncate(true) .open(world_path)?; file.write_all(text.as_bytes())?; } if do_print { println!("{}", text); } Ok(()) } }