use std::path::Path;
use std::path::PathBuf;
use std::marker::PhantomData; use install_framework_core::command::Interpreter;
use install_framework_core::command::InstallCommand;
use crate::error::Error;
use crate::cache::Cache;
pub struct StatusInterpreter<'a, TError: Error>
{
cache: &'a mut Cache<TError>,
content_dir: &'a Path,
bin_dir: &'a Path,
installed: bool,
useless: PhantomData<TError>
}
impl <'a, TError: Error> StatusInterpreter<'a, TError>
{
pub fn new(content_dir: &'a Path, bin_dir: &'a Path, cache: &'a mut Cache<TError>) -> StatusInterpreter<'a, TError>
{
return StatusInterpreter
{
cache: cache,
content_dir: content_dir,
bin_dir: bin_dir,
installed: true,
useless: PhantomData
};
}
pub fn is_installed(&self) -> bool
{
return self.installed;
}
fn download_file(&mut self, resid: usize, filename: String) -> Result<(), TError::ErrorType>
{
let outfile = self.cache.get_path(Path::new(&filename))?;
self.cache.insert(resid, outfile);
return Ok(());
}
fn unpack_cached(&mut self, resid: usize, path: String) -> Result<(), TError::ErrorType>
{
if !path.ends_with(".zip")
{
return Err(TError::generic(String::from("Only ZIP archives are supported")));
}
let computed1 = self.cache.parse_string(&path[..path.len() - 4])?;
let outpath = self.cache.get_path(Path::new(&computed1))?;
self.cache.insert(resid, outpath);
return Ok(());
}
fn extract_resource(&mut self, resid: usize, path: &'static str) -> Result<(), TError::ErrorType>
{
let name =
{
if let Some(id) = path.rfind('/')
{
&path[id + 1..]
}
else
{
path
}
};
let outpath = self.cache.get_path(Path::new(name))?;
self.cache.insert(resid, outpath);
return Ok(());
}
fn install_cached(&mut self, path: String, folder: usize) -> Result<(), TError::ErrorType>
{
let src = PathBuf::from(self.cache.parse_string(&path)?);
let dst;
let dstf;
if folder == 0
{
dst = self.content_dir;
}
else
{
dst = Path::new(self.cache.get(folder)?);
}
if let Some(name) = src.file_name()
{
dstf = dst.join(name);
}
else
{
dstf = dst.join(&src);
}
if !dstf.exists()
{
self.installed = false;
}
return Ok(());
}
fn install_resource(&mut self, path: &'static str, folder: usize) -> Result<(), TError::ErrorType>
{
let dst;
if folder == 0
{
dst = self.content_dir;
}
else
{
dst = Path::new(self.cache.get(folder)?);
}
let name =
{
if let Some(id) = path.rfind('/')
{
&path[id + 1..]
}
else
{
path
}
};
let dstf = dst.join(name);
if !dstf.exists()
{
self.installed = false;
}
return Ok(());
}
}
impl <TError: Error> Interpreter<InstallCommand> for StatusInterpreter<'_, TError>
{
type ErrorType = TError::ErrorType;
fn execute(&mut self, resid: usize, cmd: InstallCommand) -> Result<(), TError::ErrorType>
{
match cmd
{
InstallCommand::DownloadFile(f, _, _) => self.download_file(resid, f)?,
InstallCommand::UnpackCached(p) => self.unpack_cached(resid, p)?,
InstallCommand::ExtractResource(p) => self.extract_resource(resid, p)?,
InstallCommand::InstallCached(p, f) => self.install_cached(p, f)?,
InstallCommand::InstallResource(p, f) => self.install_resource(p, f)?,
InstallCommand::CreateFolder(s) =>
{
let dir = self.content_dir.join(Path::new(&s));
if !dir.exists()
{
self.installed = false;
}
self.cache.insert(resid, dir);
},
InstallCommand::AddToPath(s) =>
{
let dir = self.bin_dir.join(Path::new(&s));
if !dir.exists()
{
self.installed = false;
}
},
_ =>
{
}
}
return Ok(());
}
fn progress(&mut self, _: usize, _: usize) -> Result<(), Self::ErrorType>
{
return Ok(());
}
}