diff options
author | Daniel Schadt <kingdread@gmx.de> | 2021-11-09 12:46:43 +0100 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2021-11-09 12:50:33 +0100 |
commit | d21c5dc9c53b02620fce916ffc1a2695e9d3f698 (patch) | |
tree | fb17ba6ee4e0a1ed532ab6e570418abff5264616 /src/world.rs | |
parent | 919796ec954414ae16f113896bdf212381c96437 (diff) | |
download | modderbaas-d21c5dc9c53b02620fce916ffc1a2695e9d3f698.tar.gz modderbaas-d21c5dc9c53b02620fce916ffc1a2695e9d3f698.tar.bz2 modderbaas-d21c5dc9c53b02620fce916ffc1a2695e9d3f698.zip |
Separate the binary and library
This uses the workspace feature of cargo, with the benefit that
1) We can more cleanly group the binary (user facing) code from the
library
2) We can have dependencies that apply to the binary only
The first point could've been achieved without workspaces (Cargo
supports both binaries and libraries in a crate), but the second point
is what really makes this approach a lot better.
Diffstat (limited to 'src/world.rs')
-rw-r--r-- | src/world.rs | 97 |
1 files changed, 0 insertions, 97 deletions
diff --git a/src/world.rs b/src/world.rs deleted file mode 100644 index 5dce6d0..0000000 --- a/src/world.rs +++ /dev/null @@ -1,97 +0,0 @@ -//! Module to interact with Minetest worlds (savegames). -//! -//! The main object is [`World`], which represents a Minetest world on-disk. -use std::{ - collections::HashMap, - fmt, - path::{Path, PathBuf}, -}; - -use super::{ - error::{Error, Result}, - kvstore, - minemod::ModId, -}; - -/// Represents an on-disk Minetest world. -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct World { - path: PathBuf, -} - -impl World { - /// Open the given directory as a [`World`]. - pub fn open<P: AsRef<Path>>(path: P) -> Result<World> { - World::open_path(path.as_ref()) - } - - fn open_path(path: &Path) -> Result<World> { - let conf = path.join("world.mt"); - if !conf.is_file() { - return Err(Error::InvalidWorldDir(path.into())); - } - - Ok(World { path: path.into() }) - } - - fn conf(&self) -> Result<HashMap<String, String>> { - let conf = self.path.join("world.mt"); - kvstore::read(&conf) - } - - /// Returns the name of the world. - pub fn world_name(&self) -> Result<String> { - let fallback = self - .path - .file_name() - .map(|s| s.to_str().expect("Non-UTF8 directory encountered")); - - let conf = self.conf()?; - conf.get("world_name") - .map(String::as_str) - .or(fallback) - .ok_or_else(|| Error::InvalidWorldDir(self.path.clone())) - .map(Into::into) - } - - /// Extract the game that this world uses. - pub fn game_id(&self) -> Result<String> { - let conf = self.conf()?; - conf.get("gameid").ok_or(Error::NoGameSet).map(Into::into) - } - - /// Returns all mods that are loaded in this world. - /// - /// This returns mods that are explicitely loaded in the config, but not mods that are loaded - /// through the game. - pub fn mods(&self) -> Result<Vec<ModId>> { - let conf = self.conf()?; - const PREFIX_LEN: usize = "load_mod_".len(); - Ok(conf - .iter() - .filter(|(k, _)| k.starts_with("load_mod_")) - .filter(|(_, v)| *v == "true") - .map(|i| i.0[PREFIX_LEN..].into()) - .collect()) - } - - /// Enable the given mod. - /// - /// Note that this function does not ensure that the mod exists on-disk, nor does it do any - /// dependency checks. It simply adds the right `load_mod`-line to the world configuration - /// file. - pub fn enable_mod(&self, mod_id: &str) -> Result<()> { - let mut conf = self.conf()?; - let key = format!("load_mod_{}", mod_id); - conf.entry(key) - .and_modify(|e| *e = "true".into()) - .or_insert_with(|| "true".into()); - kvstore::write(&conf, &self.path.join("world.mt")) - } -} - -impl fmt::Display for World { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", self.world_name().map_err(|_| fmt::Error)?) - } -} |