refactor errors in store.rs
This commit is contained in:
parent
a7d5819a78
commit
71dcc94e29
@ -8,10 +8,17 @@ use super::Descr;
|
|||||||
pub struct Limits {}
|
pub struct Limits {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AllDescrsError {
|
pub enum WriteFileError {
|
||||||
|
FileNotFound,
|
||||||
Unexpected(Box<dyn Error>),
|
Unexpected(Box<dyn Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Error + 'static> From<E> for WriteFileError {
|
||||||
|
fn from(e: E) -> WriteFileError {
|
||||||
|
WriteFileError::Unexpected(Box::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SyncError {
|
pub enum SyncError {
|
||||||
InvalidURL,
|
InvalidURL,
|
||||||
@ -19,12 +26,25 @@ pub enum SyncError {
|
|||||||
Unexpected(Box<dyn Error>),
|
Unexpected(Box<dyn Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Error + 'static> From<E> for SyncError {
|
||||||
|
fn from(e: E) -> SyncError {
|
||||||
|
SyncError::Unexpected(Box::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WriteFileError {
|
pub enum AllDescrsError {
|
||||||
FileNotFound,
|
|
||||||
Unexpected(Box<dyn Error>),
|
Unexpected(Box<dyn Error>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<E: Error + 'static> From<E> for AllDescrsError {
|
||||||
|
fn from(e: E) -> AllDescrsError {
|
||||||
|
AllDescrsError::Unexpected(Box::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type AllDescrsResult<T> = Result<T, AllDescrsError>;
|
||||||
|
|
||||||
pub trait Store {
|
pub trait Store {
|
||||||
fn write_file<W>(&self, descr: &Descr, path: &str, into: &mut W) -> Result<(), WriteFileError>
|
fn write_file<W>(&self, descr: &Descr, path: &str, into: &mut W) -> Result<(), WriteFileError>
|
||||||
where
|
where
|
||||||
@ -32,9 +52,7 @@ pub trait Store {
|
|||||||
|
|
||||||
fn sync(&self, descr: &Descr, limits: Limits) -> Result<(), SyncError>;
|
fn sync(&self, descr: &Descr, limits: Limits) -> Result<(), SyncError>;
|
||||||
|
|
||||||
fn all_descrs(
|
fn all_descrs(&self) -> AllDescrsResult<Box<dyn Iterator<Item = AllDescrsResult<Descr>> + '_>>;
|
||||||
&self,
|
|
||||||
) -> Result<Box<dyn Iterator<Item = Result<Descr, AllDescrsError>> + '_>, AllDescrsError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod git {
|
pub mod git {
|
||||||
@ -43,24 +61,8 @@ pub mod git {
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
|
|
||||||
use gix::clone::Error as gixCloneErr;
|
|
||||||
use gix::progress::Discard;
|
use gix::progress::Discard;
|
||||||
|
|
||||||
// Catching error from gix::prepare_clone_bare
|
|
||||||
impl From<gixCloneErr> for SyncError {
|
|
||||||
fn from(e: gixCloneErr) -> SyncError {
|
|
||||||
match e {
|
|
||||||
gixCloneErr::Init(gix::init::Error::InvalidBranchName { .. }) => {
|
|
||||||
SyncError::InvalidBranchName
|
|
||||||
}
|
|
||||||
gixCloneErr::UrlParse(_) | gixCloneErr::CanonicalizeUrl { .. } => {
|
|
||||||
SyncError::InvalidURL
|
|
||||||
}
|
|
||||||
_ => SyncError::Unexpected(Box::from(e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Store<'a> {
|
pub struct Store<'a> {
|
||||||
dir_path: &'a Path,
|
dir_path: &'a Path,
|
||||||
}
|
}
|
||||||
@ -93,47 +95,51 @@ pub mod git {
|
|||||||
// if the path doesn't exist then use the gix clone feature to clone it into the
|
// if the path doesn't exist then use the gix clone feature to clone it into the
|
||||||
// directory.
|
// directory.
|
||||||
if fs::read_dir(repo_path).is_err() {
|
if fs::read_dir(repo_path).is_err() {
|
||||||
fs::create_dir_all(repo_path).map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
fs::create_dir_all(repo_path)?;
|
||||||
|
|
||||||
let Descr::Git { url, branch_name } = descr;
|
let Descr::Git { url, branch_name } = descr;
|
||||||
|
|
||||||
let (repo, _) = gix::prepare_clone_bare(url.clone(), repo_path)?
|
use gix::clone::Error as gixCloneErr;
|
||||||
|
|
||||||
|
let (repo, _) = gix::prepare_clone_bare(url.clone(), repo_path)
|
||||||
|
.map_err(|e| match e {
|
||||||
|
gixCloneErr::Init(gix::init::Error::InvalidBranchName { .. }) => {
|
||||||
|
SyncError::InvalidBranchName
|
||||||
|
}
|
||||||
|
gixCloneErr::UrlParse(_) | gixCloneErr::CanonicalizeUrl { .. } => {
|
||||||
|
SyncError::InvalidURL
|
||||||
|
}
|
||||||
|
_ => SyncError::Unexpected(Box::from(e)),
|
||||||
|
})?
|
||||||
.fetch_only(Discard, should_interrupt)
|
.fetch_only(Discard, should_interrupt)
|
||||||
.map_err(|_| SyncError::InvalidURL)?;
|
.map_err(|_| SyncError::InvalidURL)?;
|
||||||
|
|
||||||
// Check to make sure the branch name exists
|
// Check to make sure the branch name exists
|
||||||
// TODO if this fails we should delete the whole repo
|
// TODO if this fails we should delete the whole repo
|
||||||
repo.try_find_reference(&Self::branch_ref(branch_name))
|
repo.try_find_reference(&Self::branch_ref(branch_name))?
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?
|
|
||||||
.ok_or(SyncError::InvalidBranchName)?;
|
.ok_or(SyncError::InvalidBranchName)?;
|
||||||
|
|
||||||
// Add the descr to the repo directory, so we can know the actual descr later
|
// Add the descr to the repo directory, so we can know the actual descr later
|
||||||
// TODO if this fails we should delete the whole repo
|
// TODO if this fails we should delete the whole repo
|
||||||
let descr_file = fs::File::create(self.descr_file_path(descr.id().as_ref()))
|
let descr_file = fs::File::create(self.descr_file_path(descr.id().as_ref()))?;
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
serde_json::to_writer(descr_file, &descr)
|
serde_json::to_writer(descr_file, &descr)?;
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let direction = gix::remote::Direction::Fetch;
|
let direction = gix::remote::Direction::Fetch;
|
||||||
|
|
||||||
let repo = gix::open(repo_path).map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
let repo = gix::open(repo_path)?;
|
||||||
|
|
||||||
let remote = repo
|
let remote = repo
|
||||||
.find_default_remote(direction)
|
.find_default_remote(direction)
|
||||||
.ok_or_else(|| SyncError::Unexpected(Box::from("no default configured")))?
|
.ok_or_else(|| SyncError::Unexpected(Box::from("no default configured")))??;
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
remote
|
remote
|
||||||
.connect(direction)
|
.connect(direction)?
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?
|
.prepare_fetch(Discard, Default::default())?
|
||||||
.prepare_fetch(Discard, Default::default())
|
.receive(Discard, should_interrupt)?;
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?
|
|
||||||
.receive(Discard, should_interrupt)
|
|
||||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -154,69 +160,51 @@ pub mod git {
|
|||||||
let mut clean_path = Path::new(path);
|
let mut clean_path = Path::new(path);
|
||||||
clean_path = clean_path.strip_prefix("/").unwrap_or(clean_path);
|
clean_path = clean_path.strip_prefix("/").unwrap_or(clean_path);
|
||||||
|
|
||||||
let repo =
|
let repo = gix::open(repo_path)?;
|
||||||
gix::open(repo_path).map_err(|e| WriteFileError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
let commit_object_id = repo
|
let commit_object_id = repo.find_reference(branch_ref)?.peel_to_id_in_place()?;
|
||||||
.find_reference(branch_ref)
|
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
|
||||||
.peel_to_id_in_place()
|
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
let tree_object_id = repo
|
let tree_object_id = repo
|
||||||
.find_object(commit_object_id)
|
.find_object(commit_object_id)?
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
.try_to_commit_ref()?
|
||||||
.try_to_commit_ref()
|
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
|
||||||
.tree();
|
.tree();
|
||||||
|
|
||||||
let file_object = repo
|
let file_object = repo
|
||||||
.find_object(tree_object_id)
|
.find_object(tree_object_id)?
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
.peel_to_tree()?
|
||||||
.peel_to_tree()
|
.lookup_entry_by_path(clean_path)?
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
|
||||||
.lookup_entry_by_path(clean_path)
|
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?
|
|
||||||
.ok_or(WriteFileError::FileNotFound)?
|
.ok_or(WriteFileError::FileNotFound)?
|
||||||
.object()
|
.object()?;
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
into.write_all(file_object.data.as_ref())
|
into.write_all(file_object.data.as_ref())?;
|
||||||
.map_err(|e| WriteFileError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_descrs(
|
fn all_descrs(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Box<dyn Iterator<Item = Result<Descr, AllDescrsError>> + '_>, AllDescrsError>
|
) -> AllDescrsResult<Box<dyn Iterator<Item = AllDescrsResult<Descr>> + '_>> {
|
||||||
{
|
let inner_iter = fs::read_dir(self.dir_path)?.map(
|
||||||
let inner_iter = fs::read_dir(self.dir_path)
|
|dir_entry_res: io::Result<fs::DirEntry>| -> Result<Descr, AllDescrsError> {
|
||||||
.map_err(|e| AllDescrsError::Unexpected(Box::from(e)))?
|
let descr_id: String = dir_entry_res?
|
||||||
.map(
|
.file_name()
|
||||||
|dir_entry_res: io::Result<fs::DirEntry>| -> Result<Descr, AllDescrsError> {
|
.to_str()
|
||||||
let descr_id: String = dir_entry_res
|
.ok_or_else(|| {
|
||||||
.map_err(|e| AllDescrsError::Unexpected(Box::from(e)))?
|
AllDescrsError::Unexpected(Box::from(
|
||||||
.file_name()
|
"couldn't convert os string to &str",
|
||||||
.to_str()
|
))
|
||||||
.ok_or_else(|| {
|
})?
|
||||||
AllDescrsError::Unexpected(Box::from(
|
.into();
|
||||||
"couldn't convert os string to &str",
|
|
||||||
))
|
|
||||||
})?
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let descr_file_path = self.descr_file_path(descr_id.as_ref());
|
let descr_file_path = self.descr_file_path(descr_id.as_ref());
|
||||||
|
|
||||||
let descr_file = fs::File::open(descr_file_path)
|
let descr_file = fs::File::open(descr_file_path)?;
|
||||||
.map_err(|e| AllDescrsError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
let descr = serde_json::from_reader(descr_file)
|
let descr = serde_json::from_reader(descr_file)?;
|
||||||
.map_err(|e| AllDescrsError::Unexpected(Box::from(e)))?;
|
|
||||||
|
|
||||||
Ok(descr)
|
Ok(descr)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(Box::from(inner_iter))
|
Ok(Box::from(inner_iter))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user