aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2021-11-09 18:51:42 +0100
committerDaniel Schadt <kingdread@gmx.de>2021-11-09 18:51:42 +0100
commit0568defd3fe3481035b2d249ea2376f3ffdf69c1 (patch)
treed821e8a5c2f4a322f342e59f95c02e8fdb18e3f0
parent1db932c9f435fb54a3ca58333495d1e24ca7400f (diff)
downloadmodderbaas-0568defd3fe3481035b2d249ea2376f3ffdf69c1.tar.gz
modderbaas-0568defd3fe3481035b2d249ea2376f3ffdf69c1.tar.bz2
modderbaas-0568defd3fe3481035b2d249ea2376f3ffdf69c1.zip
implement a simple directory installer
-rw-r--r--modderbaas/src/baas.rs48
1 files changed, 47 insertions, 1 deletions
diff --git a/modderbaas/src/baas.rs b/modderbaas/src/baas.rs
index c88e2b4..098c7dd 100644
--- a/modderbaas/src/baas.rs
+++ b/modderbaas/src/baas.rs
@@ -1,10 +1,14 @@
//! This module contains functions to query & manipulate the global Minetest installation.
-use std::{collections::HashMap, path::PathBuf};
+use std::{
+ collections::HashMap,
+ path::{Path, PathBuf},
+};
use dirs;
use log::debug;
use super::{
+ contentdb::ContentDb,
download::{Downloader, Source},
error::{Error, Result},
game::Game,
@@ -355,3 +359,45 @@ pub trait Installer {
Ok(world.enable_mod(&minemod.mod_id()?)?)
}
}
+
+/// An [`Installer`] that simply installs mods to the given directory.
+///
+/// It resolves mods by checking if there is a single candidate. If yes, that one is taken - if
+/// not, an error is returned ([`Error::AmbiguousModId`]). No user interaction is expected or done.
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct DirInstaller<'p> {
+ dir: &'p Path,
+}
+
+impl<'p> DirInstaller<'p> {
+ /// Create a new dir installer that installs mods to the given directory.
+ pub fn new(dir: &'p Path) -> Self {
+ DirInstaller { dir }
+ }
+
+ /// The path to the directory in which this installer installs mods.
+ pub fn dir(&self) -> &Path {
+ self.dir
+ }
+}
+
+impl<'p> Installer for DirInstaller<'p> {
+ type Error = Error;
+
+ fn resolve(&mut self, mod_id: &str) -> Result<Source, Self::Error> {
+ let content_db = ContentDb::new();
+ let candidates = content_db.resolve(mod_id)?;
+ if candidates.len() == 1 {
+ Ok(Source::Http(candidates.into_iter().next().unwrap().url))
+ } else {
+ Err(Error::AmbiguousModId(mod_id.into()))
+ }
+ }
+
+ fn install_mod(
+ &mut self,
+ mod_or_pack: &dyn ModContainer,
+ ) -> Result<Box<dyn ModContainer>, Self::Error> {
+ mod_or_pack.install_to(self.dir)
+ }
+}