Implement origin::fs
This commit is contained in:
parent
a04855a252
commit
3f7624190b
17
src/main.rs
17
src/main.rs
@ -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(),
|
||||||
|
@ -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
93
src/origin/fs.rs
Normal 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(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user