106 lines
2.8 KiB
Rust
106 lines
2.8 KiB
Rust
use std::path::Path;
|
|
use crate::commands::status::{State, LocalObj};
|
|
use crate::services::api::ApiError;
|
|
use crate::store::object;
|
|
use crate::services::req_props::{ObjProps, ReqProps};
|
|
use crate::commands::push::new::New;
|
|
//use crate::commands::push::new_dir::NewDir;
|
|
//use crate::commands::push::deleted::Deleted;
|
|
|
|
#[derive(Debug)]
|
|
pub enum PushState {
|
|
Done,
|
|
Valid,
|
|
Conflict,
|
|
Error,
|
|
}
|
|
|
|
pub enum PushFlowState {
|
|
Whitelisted,
|
|
NotOnRemote,
|
|
RemoteIsNewer,
|
|
LocalIsNewer,
|
|
Error,
|
|
}
|
|
|
|
pub trait PushChange {
|
|
fn can_push(&self, whitelist: Option<&Path>) -> PushState;
|
|
fn try_push(&self, whitelist: Option<&Path>);
|
|
fn push(&self);
|
|
|
|
fn is_whitelisted(&self, obj: &LocalObj, path: Option<&Path>) -> bool {
|
|
match path {
|
|
Some(p) => obj.path.starts_with(p),
|
|
None => false,
|
|
}
|
|
}
|
|
|
|
fn flow(&self, obj: &LocalObj, whitelist: Option<&Path>) -> PushFlowState {
|
|
if self.is_whitelisted(obj, whitelist) {
|
|
return PushFlowState::Whitelisted;
|
|
}
|
|
|
|
// check if exist on server
|
|
let res = ReqProps::new()
|
|
.set_url(obj.path.to_str().unwrap())
|
|
.getlastmodified()
|
|
.send_req_single();
|
|
|
|
let obj_data = match res {
|
|
Ok(obj) => Ok(Some(obj)),
|
|
Err(ApiError::IncorrectRequest(err)) => {
|
|
if err.status() == 404 {
|
|
Ok(None)
|
|
} else {
|
|
Err(())
|
|
}
|
|
},
|
|
Err(_) => Err(()),
|
|
};
|
|
|
|
let obj_data = match obj_data {
|
|
Ok(Some(info)) => info,
|
|
Ok(None) => return PushFlowState::NotOnRemote,
|
|
Err(_) => return PushFlowState::Error,
|
|
};
|
|
|
|
// check if remote is newest
|
|
let last_sync_ts = object::get_timestamp(obj.path.to_str().unwrap().to_string()).unwrap();
|
|
let remote_ts = obj_data.lastmodified.unwrap().timestamp_millis();
|
|
|
|
if last_sync_ts < remote_ts {
|
|
PushFlowState::RemoteIsNewer
|
|
} else {
|
|
PushFlowState::LocalIsNewer
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct PushFactory;
|
|
|
|
impl PushFactory {
|
|
pub fn new(&self, obj: LocalObj) -> Box<dyn PushChange> {
|
|
match obj.state {
|
|
State::New => Box::new(New { obj }),
|
|
State::Renamed => todo!(),
|
|
State::Modified => todo!(),
|
|
State::Deleted => todo!(),
|
|
//State::Deleted => Box::new(Deleted {}),
|
|
State::Default => todo!(),
|
|
}
|
|
}
|
|
|
|
pub fn new_dir(&self, obj: LocalObj) -> Box<dyn PushChange> {
|
|
match obj.state {
|
|
//State::New => Box::new(NewDir {}),
|
|
State::New => todo!(),
|
|
State::Renamed => todo!(),
|
|
State::Modified => todo!(),
|
|
State::Deleted => todo!(),
|
|
State::Default => todo!(),
|
|
}
|
|
}
|
|
}
|
|
|
|
|