Compare commits

..

2 Commits

Author SHA1 Message Date
3f7624190b Implement origin::fs 2024-05-30 23:46:05 +02:00
a04855a252 Redifine origin::mux to be actually usable 2024-05-30 23:46:01 +02:00
5 changed files with 121 additions and 15 deletions

View File

@ -103,7 +103,22 @@ async fn main() {
) )
} }
let origin_store = domani::origin::git::Proxy::new(); let origin_store = {
use domani::origin::*;
use std::sync::Arc;
let git = git::Proxy::new();
let fs = Arc::from(fs::new());
mux::new(
move |descr: &Descr| -> Option<Arc<dyn Store + Sync + Send>> {
match descr {
Descr::Git { .. } => Some(git.clone()),
Descr::FS { .. } => Some(fs.clone()),
}
},
)
};
let domain_checker = domani::domain::checker::DNSChecker::new( let domain_checker = domani::domain::checker::DNSChecker::new(
domani::token::MemStore::new(), domani::token::MemStore::new(),

View File

@ -1,4 +1,5 @@
pub mod descr; pub mod descr;
pub mod fs;
pub mod git; pub mod git;
pub mod mux; pub mod mux;
@ -22,7 +23,7 @@ pub enum SyncError {
Unexpected(#[from] unexpected::Error), Unexpected(#[from] unexpected::Error),
} }
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug, PartialEq)]
pub enum GetFileError { pub enum GetFileError {
#[error("descr not synced")] #[error("descr not synced")]
DescrNotSynced, DescrNotSynced,

93
src/origin/fs.rs Normal file
View File

@ -0,0 +1,93 @@
use crate::error::unexpected::{Intoable, Mappable};
use crate::{origin, util};
use std::path;
#[derive(Clone)]
pub struct FS {}
pub fn new() -> FS {
FS {}
}
fn path_is_clean<P: AsRef<path::Path>>(p: P) -> bool {
use path::Component;
for c in p.as_ref().components() {
match c {
Component::RootDir => (),
Component::Normal(_) => (),
_ => return false,
}
}
true
}
impl origin::Store for FS {
fn sync(&self, _: &origin::Descr) -> util::BoxFuture<'_, Result<(), origin::SyncError>> {
Box::pin(futures::future::ready(Ok(())))
}
fn get_file(
&self,
descr: &origin::Descr,
path: &str,
) -> util::BoxFuture<'_, Result<util::BoxByteStream, origin::GetFileError>> {
if !path_is_clean(path) {
return Box::pin(futures::future::ready(Err(
origin::GetFileError::FileNotFound,
)));
}
let descr = descr.clone();
let path: path::PathBuf = path.to_string().into();
Box::pin(async move {
let root_path = if let origin::descr::Descr::FS { path } = descr {
path
} else {
panic!("cannot deconstruct {descr:?} to FS")
};
let path = path
.strip_prefix("/")
.or_unexpected_while("relative path given to get_file")?;
let path = root_path.as_ref().join(path);
let f = tokio::fs::File::open(path).await.map_err(|e| {
use std::io::ErrorKind;
match e.kind() {
ErrorKind::NotFound => origin::GetFileError::FileNotFound,
_ => e.into_unexpected().into(),
}
})?;
if f.metadata()
.await
.or_unexpected_while("getting file metadata")?
.is_dir()
{
return Err(origin::GetFileError::PathIsDirectory);
}
Ok(util::BoxByteStream::from_async_read(f))
})
}
}
#[cfg(test)]
mod fs_tests {
use super::*;
use crate::origin::{self, Store};
#[tokio::test]
async fn path_is_directory() {
let fs = new();
let descr = origin::Descr::FS {
path: ".".parse().unwrap(),
};
assert_eq!(
origin::GetFileError::PathIsDirectory,
fs.get_file(&descr, "/src").await.err().unwrap(),
)
}
}

View File

@ -33,8 +33,8 @@ pub struct Proxy {
} }
impl Proxy { impl Proxy {
pub fn new() -> Proxy { pub fn new() -> sync::Arc<Self> {
Proxy::default() sync::Arc::new(Proxy::default())
} }
fn deconstruct_descr(descr: &origin::Descr) -> (&origin::descr::GitUrl, &str) { fn deconstruct_descr(descr: &origin::Descr) -> (&origin::descr::GitUrl, &str) {

View File

@ -1,27 +1,24 @@
use crate::error::unexpected::Mappable; use crate::error::unexpected::Mappable;
use crate::{origin, util}; use crate::{origin, util};
use std::sync::Arc;
pub struct Store<F, S> pub struct Store<F>
where where
F: Fn(&origin::Descr) -> Option<S> + Sync + Send, F: Fn(&origin::Descr) -> Option<Arc<dyn origin::Store + Sync + Send>> + Sync + Send,
{ {
mapping_fn: F, mapping_fn: F,
} }
impl<F, S> Store<F, S> pub fn new<F>(mapping_fn: F) -> Store<F>
where where
S: origin::Store + Sync + Send + 'static, F: Fn(&origin::Descr) -> Option<Arc<dyn origin::Store + Sync + Send>> + Sync + Send,
F: Fn(&origin::Descr) -> Option<S> + Sync + Send,
{ {
pub fn new(mapping_fn: F) -> Store<F, S> { Store { mapping_fn }
Store { mapping_fn }
}
} }
impl<F, S> origin::Store for Store<F, S> impl<F> origin::Store for Store<F>
where where
S: origin::Store + Sync + Send + 'static, F: Fn(&origin::Descr) -> Option<Arc<dyn origin::Store + Sync + Send>> + Sync + Send,
F: Fn(&origin::Descr) -> Option<S> + Sync + Send,
{ {
fn sync(&self, descr: &origin::Descr) -> util::BoxFuture<'_, Result<(), origin::SyncError>> { fn sync(&self, descr: &origin::Descr) -> util::BoxFuture<'_, Result<(), origin::SyncError>> {
let descr = descr.clone(); let descr = descr.clone();