Compare commits

..

No commits in common. "7daa86473975ee2edaca058b6497dcc108c89cdb" and "cab7a837a744daebe6fb20231674c8ea741621cc" have entirely different histories.

9 changed files with 121 additions and 167 deletions

View File

@ -1,9 +1,9 @@
use std::error::Error;
use std::net; use std::net;
use std::str::FromStr; use std::str::FromStr;
use std::sync; use std::sync;
use crate::error::MapUnexpected; use crate::domain;
use crate::{domain, error};
use trust_dns_client::client::{AsyncClient, ClientHandle}; use trust_dns_client::client::{AsyncClient, ClientHandle};
use trust_dns_client::rr::{DNSClass, Name, RData, RecordType}; use trust_dns_client::rr::{DNSClass, Name, RData, RecordType};
@ -15,7 +15,7 @@ pub enum NewDNSCheckerError {
InvalidResolverAddress, InvalidResolverAddress,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -27,7 +27,7 @@ pub enum CheckDomainError {
ChallengeTokenNotSet, ChallengeTokenNotSet,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
pub struct DNSChecker { pub struct DNSChecker {
@ -50,7 +50,7 @@ pub fn new(
let (client, bg) = tokio_runtime let (client, bg) = tokio_runtime
.block_on(async { AsyncClient::connect(stream).await }) .block_on(async { AsyncClient::connect(stream).await })
.map_unexpected()?; .map_err(|e| NewDNSCheckerError::Unexpected(Box::from(e)))?;
tokio_runtime.spawn(bg); tokio_runtime.spawn(bg);
@ -68,15 +68,18 @@ impl DNSChecker {
) -> Result<(), CheckDomainError> { ) -> Result<(), CheckDomainError> {
let domain = &domain.inner; let domain = &domain.inner;
// check that the A is installed correctly on the domain // check that the AAAA is installed correctly on the domain
{ {
let response = self let response = match self
.client .client
.lock() .lock()
.await .await
.query(domain.clone(), DNSClass::IN, RecordType::A) .query(domain.clone(), DNSClass::IN, RecordType::A)
.await .await
.map_unexpected()?; {
Ok(res) => res,
Err(e) => return Err(CheckDomainError::Unexpected(Box::from(e))),
};
let records = response.answers(); let records = response.answers();
@ -95,17 +98,20 @@ impl DNSChecker {
// check that the TXT record with the challenge token is correctly installed on the domain // check that the TXT record with the challenge token is correctly installed on the domain
{ {
let domain = Name::from_str("_domiply_challenge") let domain = Name::from_str("_domiply_challenge")
.map_unexpected()? .map_err(|e| CheckDomainError::Unexpected(Box::from(e)))?
.append_domain(domain) .append_domain(domain)
.map_unexpected()?; .map_err(|e| CheckDomainError::Unexpected(Box::from(e)))?;
let response = self let response = match self
.client .client
.lock() .lock()
.await .await
.query(domain, DNSClass::IN, RecordType::TXT) .query(domain, DNSClass::IN, RecordType::TXT)
.await .await
.map_unexpected()?; {
Ok(res) => res,
Err(e) => return Err(CheckDomainError::Unexpected(Box::from(e))),
};
let records = response.answers(); let records = response.answers();

View File

@ -1,8 +1,9 @@
use std::error::Error;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{fs, io, sync}; use std::{fs, io, sync};
use crate::error::{MapUnexpected, ToUnexpected}; use crate::domain;
use crate::{domain, error, origin}; use crate::origin::Descr;
use hex::ToHex; use hex::ToHex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -11,13 +12,13 @@ use sha2::{Digest, Sha256};
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
/// Values which the owner of a domain can configure when they install a domain. /// Values which the owner of a domain can configure when they install a domain.
pub struct Config { pub struct Config {
pub origin_descr: origin::Descr, pub origin_descr: Descr,
} }
impl Config { impl Config {
pub fn hash(&self) -> Result<String, error::Unexpected> { pub fn hash(&self) -> Result<String, Box<dyn Error>> {
let mut h = Sha256::new(); let mut h = Sha256::new();
serde_json::to_writer(&mut h, self).map_unexpected()?; serde_json::to_writer(&mut h, self)?;
Ok(h.finalize().encode_hex::<String>()) Ok(h.finalize().encode_hex::<String>())
} }
} }
@ -28,13 +29,13 @@ pub enum GetError {
NotFound, NotFound,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum SetError { pub enum SetError {
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[mockall::automock] #[mockall::automock]
@ -73,19 +74,21 @@ impl Store for sync::Arc<FSStore> {
let config_file = let config_file =
fs::File::open(self.config_file_path(domain)).map_err(|e| match e.kind() { fs::File::open(self.config_file_path(domain)).map_err(|e| match e.kind() {
io::ErrorKind::NotFound => GetError::NotFound, io::ErrorKind::NotFound => GetError::NotFound,
_ => e.to_unexpected().into(), _ => GetError::Unexpected(Box::from(e)),
})?; })?;
let config = serde_json::from_reader(config_file).map_unexpected()?; serde_json::from_reader(config_file).map_err(|e| GetError::Unexpected(Box::from(e)))
Ok(config)
} }
fn set(&self, domain: &domain::Name, config: &Config) -> Result<(), SetError> { fn set(&self, domain: &domain::Name, config: &Config) -> Result<(), SetError> {
fs::create_dir_all(self.config_dir_path(domain)).map_unexpected()?; fs::create_dir_all(self.config_dir_path(domain))
.map_err(|e| SetError::Unexpected(Box::from(e)))?;
let config_file = fs::File::create(self.config_file_path(domain)).map_unexpected()?; let config_file = fs::File::create(self.config_file_path(domain))
.map_err(|e| SetError::Unexpected(Box::from(e)))?;
serde_json::to_writer(config_file, config).map_unexpected()?; serde_json::to_writer(config_file, config)
.map_err(|e| SetError::Unexpected(Box::from(e)))?;
Ok(()) Ok(())
} }

View File

@ -1,8 +1,7 @@
use crate::domain::{self, checker, config}; use crate::domain::{self, checker, config};
use crate::error::{MapUnexpected, ToUnexpected}; use crate::origin;
use crate::{error, origin}; use std::error::Error;
use std::future::Future;
use std::future;
use std::{pin, sync}; use std::{pin, sync};
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -11,7 +10,7 @@ pub enum GetConfigError {
NotFound, NotFound,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
impl From<config::GetError> for GetConfigError { impl From<config::GetError> for GetConfigError {
@ -29,7 +28,7 @@ pub enum GetOriginError {
NotFound, NotFound,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
impl From<config::GetError> for GetOriginError { impl From<config::GetError> for GetOriginError {
@ -50,7 +49,7 @@ pub enum SyncError {
AlreadyInProgress, AlreadyInProgress,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
impl From<config::GetError> for SyncError { impl From<config::GetError> for SyncError {
@ -80,7 +79,7 @@ pub enum SyncWithConfigError {
ChallengeTokenNotSet, ChallengeTokenNotSet,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
impl From<origin::store::SyncError> for SyncWithConfigError { impl From<origin::store::SyncError> for SyncWithConfigError {
@ -114,30 +113,19 @@ impl From<config::SetError> for SyncWithConfigError {
} }
} }
#[mockall::automock( //#[mockall::automock]
type Origin=origin::MockOrigin;
type SyncWithConfigFuture=future::Ready<Result<(), SyncWithConfigError>>;
)]
pub trait Manager { pub trait Manager {
type Origin<'mgr>: origin::Origin + 'mgr
where
Self: 'mgr;
type SyncWithConfigFuture<'mgr>: future::Future<Output = Result<(), SyncWithConfigError>>
+ Send
+ Unpin
+ 'mgr
where
Self: 'mgr;
fn get_config(&self, domain: &domain::Name) -> Result<config::Config, GetConfigError>; fn get_config(&self, domain: &domain::Name) -> Result<config::Config, GetConfigError>;
fn get_origin(&self, domain: &domain::Name) -> Result<Self::Origin<'_>, GetOriginError>; fn get_origin(
&self,
domain: &domain::Name,
) -> Result<Box<dyn origin::Origin + '_>, GetOriginError>;
fn sync(&self, domain: &domain::Name) -> Result<(), SyncError>; fn sync(&self, domain: &domain::Name) -> Result<(), SyncError>;
fn sync_with_config( fn sync_with_config(
&self, &self,
domain: domain::Name, domain: domain::Name,
config: config::Config, config: config::Config,
) -> Self::SyncWithConfigFuture<'_>; ) -> pin::Pin<Box<dyn Future<Output = Result<(), SyncWithConfigError>> + Send + '_>>;
} }
pub trait BoxedManager: Manager + Send + Sync + Clone {} pub trait BoxedManager: Manager + Send + Sync + Clone {}
@ -182,24 +170,21 @@ where
OriginStore: origin::store::BoxedStore, OriginStore: origin::store::BoxedStore,
DomainConfigStore: config::BoxedStore, DomainConfigStore: config::BoxedStore,
{ {
type Origin<'mgr> = OriginStore::Origin<'mgr>
where Self: 'mgr;
type SyncWithConfigFuture<'mgr> = pin::Pin<Box<dyn future::Future<Output = Result<(), SyncWithConfigError>> + Send + 'mgr>>
where Self: 'mgr;
fn get_config(&self, domain: &domain::Name) -> Result<config::Config, GetConfigError> { fn get_config(&self, domain: &domain::Name) -> Result<config::Config, GetConfigError> {
Ok(self.domain_config_store.get(domain)?) Ok(self.domain_config_store.get(domain)?)
} }
fn get_origin(&self, domain: &domain::Name) -> Result<Self::Origin<'_>, GetOriginError> { fn get_origin(
&self,
domain: &domain::Name,
) -> Result<Box<dyn origin::Origin + '_>, GetOriginError> {
let config = self.domain_config_store.get(domain)?; let config = self.domain_config_store.get(domain)?;
let origin = self let origin = self
.origin_store .origin_store
.get(config.origin_descr) .get(config.origin_descr)
// if there's a config there should be an origin, any error here is unexpected // if there's a config there should be an origin, any error here is unexpected
.map_unexpected()?; .map_err(|e| GetOriginError::Unexpected(Box::from(e)))?;
Ok(origin) Ok(Box::from(origin))
} }
fn sync(&self, domain: &domain::Name) -> Result<(), SyncError> { fn sync(&self, domain: &domain::Name) -> Result<(), SyncError> {
@ -208,7 +193,7 @@ where
.sync(config.origin_descr, origin::store::Limits {}) .sync(config.origin_descr, origin::store::Limits {})
.map_err(|e| match e { .map_err(|e| match e {
origin::store::SyncError::AlreadyInProgress => SyncError::AlreadyInProgress, origin::store::SyncError::AlreadyInProgress => SyncError::AlreadyInProgress,
_ => e.to_unexpected().into(), _ => SyncError::Unexpected(Box::from(e)),
})?; })?;
Ok(()) Ok(())
} }
@ -217,9 +202,11 @@ where
&self, &self,
domain: domain::Name, domain: domain::Name,
config: config::Config, config: config::Config,
) -> Self::SyncWithConfigFuture<'_> { ) -> pin::Pin<Box<dyn Future<Output = Result<(), SyncWithConfigError>> + Send + '_>> {
Box::pin(async move { Box::pin(async move {
let config_hash = config.hash().map_unexpected()?; let config_hash = config
.hash()
.map_err(|e| SyncWithConfigError::Unexpected(e))?;
self.domain_checker self.domain_checker
.check_domain(&domain, &config_hash) .check_domain(&domain, &config_hash)

View File

@ -1,50 +0,0 @@
use std::error;
use std::fmt;
use std::fmt::Write;
#[derive(Debug, Clone)]
pub struct Unexpected(String);
impl fmt::Display for Unexpected {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Unexpected error occurred: {}", self.0)
}
}
impl error::Error for Unexpected {}
impl From<&str> for Unexpected {
fn from(s: &str) -> Self {
Unexpected(s.to_string())
}
}
pub trait ToUnexpected {
fn to_unexpected(&self) -> Unexpected;
}
impl<E: error::Error> ToUnexpected for E {
fn to_unexpected(&self) -> Unexpected {
let mut w = String::new();
write!(w, "{}", self.to_string()).expect("underlying error formatted correctly");
if let Some(src) = self.source() {
write!(w, " [{src}]").expect("underyling source formatted correctly");
}
Unexpected(w.to_string())
}
}
pub trait MapUnexpected<T> {
fn map_unexpected(self) -> Result<T, Unexpected>;
}
impl<T, E: ToUnexpected> MapUnexpected<T> for Result<T, E> {
fn map_unexpected(self) -> Result<T, Unexpected> {
match self {
Ok(t) => Ok(t),
Err(err) => Err(err.to_unexpected()),
}
}
}

View File

@ -1,4 +1,3 @@
pub mod domain; pub mod domain;
pub mod error;
pub mod origin; pub mod origin;
pub mod service; pub mod service;

View File

@ -1,4 +1,4 @@
use crate::error; use std::error::Error;
mod descr; mod descr;
pub use self::descr::Descr; pub use self::descr::Descr;
@ -10,7 +10,7 @@ pub enum ReadFileIntoError {
FileNotFound, FileNotFound,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[mockall::automock] #[mockall::automock]

View File

@ -1,4 +1,5 @@
use crate::{error, origin}; use crate::origin;
use std::error::Error;
pub mod git; pub mod git;
@ -19,7 +20,7 @@ pub enum SyncError {
AlreadyInProgress, AlreadyInProgress,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
@ -28,13 +29,13 @@ pub enum GetError {
NotFound, NotFound,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum AllDescrsError { pub enum AllDescrsError {
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
/// Used in the return from all_descrs from Store. /// Used in the return from all_descrs from Store.

View File

@ -1,7 +1,7 @@
use crate::error::{MapUnexpected, ToUnexpected}; use crate::origin;
use crate::origin::store; use crate::origin::store;
use crate::{error, origin};
use std::error::Error;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::{collections, fs, io, sync}; use std::{collections, fs, io, sync};
@ -28,16 +28,17 @@ impl origin::Origin for sync::Arc<Origin> {
let file_object = repo let file_object = repo
.find_object(self.tree_object_id) .find_object(self.tree_object_id)
.map_unexpected()? .map_err(|e| origin::ReadFileIntoError::Unexpected(Box::from(e)))?
.peel_to_tree() .peel_to_tree()
.map_unexpected()? .map_err(|e| origin::ReadFileIntoError::Unexpected(Box::from(e)))?
.lookup_entry_by_path(clean_path) .lookup_entry_by_path(clean_path)
.map_unexpected()? .map_err(|e| origin::ReadFileIntoError::Unexpected(Box::from(e)))?
.ok_or(origin::ReadFileIntoError::FileNotFound)? .ok_or(origin::ReadFileIntoError::FileNotFound)?
.object() .object()
.map_unexpected()?; .map_err(|e| origin::ReadFileIntoError::Unexpected(Box::from(e)))?;
into.write_all(file_object.data.as_ref()).map_unexpected()?; into.write_all(file_object.data.as_ref())
.map_err(|e| origin::ReadFileIntoError::Unexpected(Box::from(e)))?;
Ok(()) Ok(())
} }
@ -49,7 +50,7 @@ enum GetOriginError {
InvalidBranchName, InvalidBranchName,
#[error(transparent)] #[error(transparent)]
Unexpected(#[from] error::Unexpected), Unexpected(Box<dyn Error>),
} }
/// git::Store implements the Store trait for any Descr::Git based Origins. If any non-git /// git::Store implements the Store trait for any Descr::Git based Origins. If any non-git
@ -97,17 +98,17 @@ impl Store {
let commit_object_id = repo let commit_object_id = repo
.try_find_reference(&self.branch_ref(branch_name)) .try_find_reference(&self.branch_ref(branch_name))
.map_unexpected()? .map_err(|e| GetOriginError::Unexpected(Box::from(e)))?
.ok_or(GetOriginError::InvalidBranchName)? .ok_or(GetOriginError::InvalidBranchName)?
.peel_to_id_in_place() .peel_to_id_in_place()
.map_unexpected()? .map_err(|e| GetOriginError::Unexpected(Box::from(e)))?
.detach(); .detach();
let tree_object_id = repo let tree_object_id = repo
.find_object(commit_object_id) .find_object(commit_object_id)
.map_unexpected()? .map_err(|e| GetOriginError::Unexpected(Box::from(e)))?
.try_to_commit_ref() .try_to_commit_ref()
.map_unexpected()? .map_err(|e| GetOriginError::Unexpected(Box::from(e)))?
.tree(); .tree();
Ok(sync::Arc::from(Origin { Ok(sync::Arc::from(Origin {
@ -131,7 +132,8 @@ impl Store {
// 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_unexpected()?; fs::create_dir_all(repo_path)
.map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
let origin::Descr::Git { let origin::Descr::Git {
ref url, ref url,
@ -146,7 +148,7 @@ impl Store {
gixCloneErr::UrlParse(_) | gixCloneErr::CanonicalizeUrl { .. } => { gixCloneErr::UrlParse(_) | gixCloneErr::CanonicalizeUrl { .. } => {
store::SyncError::InvalidURL store::SyncError::InvalidURL
} }
_ => e.to_unexpected().into(), _ => store::SyncError::Unexpected(Box::from(e)),
})? })?
.fetch_only(Discard, should_interrupt) .fetch_only(Discard, should_interrupt)
.map_err(|_| store::SyncError::InvalidURL)?; .map_err(|_| store::SyncError::InvalidURL)?;
@ -154,35 +156,36 @@ impl Store {
// Check to make sure the branch name exists // Check to make sure the branch name exists
// TODO if this fails we should delete repo_path // TODO if this fails we should delete repo_path
repo.try_find_reference(&self.branch_ref(branch_name)) repo.try_find_reference(&self.branch_ref(branch_name))
.map_unexpected()? .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?
.ok_or(store::SyncError::InvalidBranchName)?; .ok_or(store::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 repo_path // TODO if this fails we should delete repo_path
let descr_file = let descr_file = fs::File::create(self.descr_file_path(descr.id().as_ref()))
fs::File::create(self.descr_file_path(descr.id().as_ref())).map_unexpected()?; .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
serde_json::to_writer(descr_file, &descr).map_unexpected()?; serde_json::to_writer(descr_file, &descr)
.map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
return Ok(repo); return Ok(repo);
} }
let direction = gix::remote::Direction::Fetch; let direction = gix::remote::Direction::Fetch;
let repo = gix::open(repo_path).map_unexpected()?; let repo = gix::open(repo_path).map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
let remote = repo let remote = repo
.find_default_remote(direction) .find_default_remote(direction)
.ok_or_else(|| error::Unexpected::from("no default configured"))? .ok_or_else(|| store::SyncError::Unexpected(Box::from("no default configured")))?
.map_unexpected()?; .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
remote remote
.connect(direction) .connect(direction)
.map_unexpected()? .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?
.prepare_fetch(Discard, Default::default()) .prepare_fetch(Discard, Default::default())
.map_unexpected()? .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?
.receive(Discard, should_interrupt) .receive(Discard, should_interrupt)
.map_unexpected()?; .map_err(|e| store::SyncError::Unexpected(Box::from(e)))?;
Ok(repo) Ok(repo)
} }
@ -253,15 +256,15 @@ impl super::Store for sync::Arc<Store> {
fs::read_dir(&repo_path).map_err(|e| match e.kind() { fs::read_dir(&repo_path).map_err(|e| match e.kind() {
io::ErrorKind::NotFound => store::GetError::NotFound, io::ErrorKind::NotFound => store::GetError::NotFound,
_ => e.to_unexpected().into(), _ => store::GetError::Unexpected(Box::from(e)),
})?; })?;
let repo = gix::open(&repo_path).map_unexpected()?; let repo = gix::open(&repo_path).map_err(|e| store::GetError::Unexpected(Box::from(e)))?;
let origin = self.get_origin(repo, descr.clone()).map_err(|e| match e { let origin = self.get_origin(repo, descr.clone()).map_err(|e| match e {
// it's not expected that the branch name is invalid at this point, it must have // it's not expected that the branch name is invalid at this point, it must have
// existed for sync to have been successful. // existed for sync to have been successful.
GetOriginError::InvalidBranchName => e.to_unexpected().into(), GetOriginError::InvalidBranchName => store::GetError::Unexpected(Box::from(e)),
GetOriginError::Unexpected(e) => store::GetError::Unexpected(e), GetOriginError::Unexpected(e) => store::GetError::Unexpected(e),
})?; })?;
@ -273,30 +276,36 @@ impl super::Store for sync::Arc<Store> {
fn all_descrs(&self) -> store::AllDescrsResult<Self::AllDescrsIter<'_>> { fn all_descrs(&self) -> store::AllDescrsResult<Self::AllDescrsIter<'_>> {
Ok(Box::from( Ok(Box::from(
fs::read_dir(&self.dir_path).map_unexpected()?.map( fs::read_dir(&self.dir_path)
|dir_entry_res: io::Result<fs::DirEntry>| -> store::AllDescrsResult<origin::Descr> { .map_err(|e| store::AllDescrsError::Unexpected(Box::from(e)))?
let descr_id: String = dir_entry_res .map(
.map_unexpected()? |dir_entry_res: io::Result<fs::DirEntry>| -> store::AllDescrsResult<origin::Descr> {
.file_name() let descr_id: String = dir_entry_res
.to_str() .map_err(|e| store::AllDescrsError::Unexpected(Box::from(e)))?
.ok_or_else(|| { .file_name()
error::Unexpected::from("couldn't convert os string to &str") .to_str()
})? .ok_or_else(|| {
.into(); store::AllDescrsError::Unexpected(Box::from(
"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());
// TODO it's possible that opening the file will fail if syncing is // TODO it's possible that opening the file will fail if syncing is
// still ongoing, as writing the descr file is the last step after // still ongoing, as writing the descr file is the last step after
// initial sync has succeeded. // initial sync has succeeded.
let descr_file = fs::File::open(descr_file_path).map_unexpected()?; let descr_file = fs::File::open(descr_file_path)
.map_err(|e| store::AllDescrsError::Unexpected(Box::from(e)))?;
let descr = serde_json::from_reader(descr_file).map_unexpected()?; let descr = serde_json::from_reader(descr_file)
.map_err(|e| store::AllDescrsError::Unexpected(Box::from(e)))?;
Ok(descr) Ok(descr)
}, },
), ),
)) ))
} }
} }

View File

@ -7,7 +7,6 @@ use std::net;
use std::str::FromStr; use std::str::FromStr;
use std::sync; use std::sync;
use crate::origin::Origin;
use crate::{domain, origin}; use crate::{domain, origin};
pub mod http_tpl; pub mod http_tpl;