diff --git a/src/commands/push.rs b/src/commands/push.rs index 48211fd..dfb57b3 100644 --- a/src/commands/push.rs +++ b/src/commands/push.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::PathBuf; use crate::services::api::ApiError; use crate::services::upload_file::UploadFile; use crate::services::delete_path::DeletePath; @@ -11,8 +11,8 @@ use crate::commands::push::push_factory::{PushFactory, PushState}; pub mod push_factory; pub mod new; -//pub mod new_dir; -//pub mod deleted; +pub mod new_dir; +pub mod deleted; pub fn push() { dbg!(status::get_all_staged()); @@ -32,25 +32,22 @@ pub fn push() { // path that certify that all its children can be push whithout hesistation // (e.g if remote dir has no changes since last sync all children // can be pushed without verification) - let whitelist: Option<&Path> = None; + let mut whitelist: Option = None; for obj in staged_objs { if obj.otype == String::from("tree") { - //let push_factory = PushFactory.new_dir(obj.clone()); - //let res = match push_factory.can_push(whitelist.clone()) { - // PushState::Valid => push_factory.push(), - // PushState::Done => (), - // PushState::Conflict => (), - // _ => todo!(), - //}; + let push_factory = PushFactory.new_dir(obj.clone()); + let res = match push_factory.can_push(&mut whitelist) { + PushState::Valid => push_factory.push(), + PushState::Done => (), + PushState::Conflict => (), + _ => todo!(), + }; - //match res { - // - //} - //dbg!("should push folder"); + dbg!("should push folder"); } else { let push_factory = PushFactory.new(obj.clone()); - match push_factory.can_push(whitelist.clone()) { + match push_factory.can_push(&mut whitelist) { PushState::Valid => push_factory.push(), PushState::Done => (), PushState::Conflict => { diff --git a/src/commands/push/deleted.rs b/src/commands/push/deleted.rs index 8b2825d..78028a5 100644 --- a/src/commands/push/deleted.rs +++ b/src/commands/push/deleted.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::PathBuf; use crate::services::api::ApiError; use crate::services::req_props::ReqProps; use crate::services::delete_path::DeletePath; @@ -12,8 +12,8 @@ pub struct Deleted { } impl PushChange for Deleted { - fn can_push(&self, whitelist: Option<&Path>) -> PushState { - match self.flow(&self.obj, whitelist) { + fn can_push(&self, whitelist: &mut Option) -> PushState { + match self.flow(&self.obj, whitelist.clone()) { PushFlowState::Whitelisted => PushState::Done, PushFlowState::NotOnRemote => PushState::Done, PushFlowState::RemoteIsNewer => PushState::Conflict, diff --git a/src/commands/push/new.rs b/src/commands/push/new.rs index 771473c..029b8ca 100644 --- a/src/commands/push/new.rs +++ b/src/commands/push/new.rs @@ -1,4 +1,4 @@ -use std::path::Path; +use std::path::PathBuf; use crate::services::api::ApiError; use crate::services::upload_file::UploadFile; use crate::store::index; @@ -11,8 +11,8 @@ pub struct New { } impl PushChange for New { - fn can_push(&self, whitelist: Option<&Path>) -> PushState { - match self.flow(&self.obj, whitelist) { + fn can_push(&self, whitelist: &mut Option) -> PushState { + match self.flow(&self.obj, whitelist.clone()) { PushFlowState::Whitelisted => PushState::Valid, PushFlowState::NotOnRemote => PushState::Valid, PushFlowState::RemoteIsNewer => PushState::Conflict, diff --git a/src/commands/push/new_dir.rs b/src/commands/push/new_dir.rs new file mode 100644 index 0000000..59042fb --- /dev/null +++ b/src/commands/push/new_dir.rs @@ -0,0 +1,57 @@ +use std::path::PathBuf; +use crate::services::api::ApiError; +use crate::services::req_props::ReqProps; +use crate::services::create_folder::CreateFolder; +use crate::store::index; +use crate::store::object::tree; +use crate::commands::status::LocalObj; +use crate::commands::push::push_factory::{PushState, PushChange, PushFactory, PushFlowState}; + +pub struct NewDir { + pub obj: LocalObj +} + +impl PushChange for NewDir { + fn can_push(&self, whitelist: &mut Option) -> PushState { + match self.flow(&self.obj, whitelist.clone()) { + PushFlowState::Whitelisted => PushState::Valid, + PushFlowState::NotOnRemote => { + *whitelist = Some(self.obj.path.clone()); + PushState::Valid + }, + PushFlowState::RemoteIsNewer => PushState::Conflict, + PushFlowState::LocalIsNewer => { + *whitelist = Some(self.obj.path.clone()); + PushState::Done + }, + PushFlowState::Error => PushState::Error, + } + } + + fn push(&self) { + let obj = &self.obj; + let res = CreateFolder::new() + .set_url(obj.path.to_str().unwrap()) + .send_with_err(); + + match res { + Err(ApiError::IncorrectRequest(err)) => { + eprintln!("fatal: error creating folder {}: {}", obj.name, err.status()); + std::process::exit(1); + }, + Err(ApiError::RequestError(_)) => { + eprintln!("fatal: request error creating folder {}", obj.name); + std::process::exit(1); + } + _ => (), + } + + // update tree + tree::add(&obj.path.clone(), "todo_date"); + + // remove index + index::rm_line(obj.path.to_str().unwrap()); + } + + fn conflict(&self) {} +} diff --git a/src/commands/push/push_factory.rs b/src/commands/push/push_factory.rs index 247ac04..f12cc82 100644 --- a/src/commands/push/push_factory.rs +++ b/src/commands/push/push_factory.rs @@ -1,11 +1,11 @@ -use std::path::Path; +use std::path::PathBuf; 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; +use crate::commands::push::new_dir::NewDir; +use crate::commands::push::deleted::Deleted; #[derive(Debug)] pub enum PushState { @@ -24,18 +24,27 @@ pub enum PushFlowState { } pub trait PushChange { - fn can_push(&self, whitelist: Option<&Path>) -> PushState; - fn try_push(&self, whitelist: Option<&Path>); + fn can_push(&self, whitelist: &mut Option) -> PushState; fn push(&self); + fn conflict(&self); - fn is_whitelisted(&self, obj: &LocalObj, path: Option<&Path>) -> bool { + fn try_push(&self, whitelist: &mut Option) { + match self.can_push(whitelist) { + PushState::Valid => self.push(), + PushState::Conflict => self.conflict(), + PushState::Done => (), + PushState::Error => (), + } + } + + fn is_whitelisted(&self, obj: &LocalObj, path: Option) -> bool { match path { Some(p) => obj.path.starts_with(p), None => false, } } - fn flow(&self, obj: &LocalObj, whitelist: Option<&Path>) -> PushFlowState { + fn flow(&self, obj: &LocalObj, whitelist: Option) -> PushFlowState { if self.is_whitelisted(obj, whitelist) { return PushFlowState::Whitelisted; } @@ -84,16 +93,14 @@ impl PushFactory { State::New => Box::new(New { obj }), State::Renamed => todo!(), State::Modified => todo!(), - State::Deleted => todo!(), - //State::Deleted => Box::new(Deleted {}), + State::Deleted => Box::new(Deleted { obj }), State::Default => todo!(), } } pub fn new_dir(&self, obj: LocalObj) -> Box { match obj.state { - //State::New => Box::new(NewDir {}), - State::New => todo!(), + State::New => Box::new(NewDir { obj }), State::Renamed => todo!(), State::Modified => todo!(), State::Deleted => todo!(), diff --git a/src/services.rs b/src/services.rs index 7db338b..70ecab3 100644 --- a/src/services.rs +++ b/src/services.rs @@ -1,4 +1,5 @@ pub mod api; +pub mod create_folder; pub mod download_files; pub mod req_props; pub mod upload_file; diff --git a/src/services/create_folder.rs b/src/services/create_folder.rs index 1dc6157..4000c97 100644 --- a/src/services/create_folder.rs +++ b/src/services/create_folder.rs @@ -6,21 +6,27 @@ pub struct CreateFolder { } impl CreateFolder { - pub fn new(url: U) -> Self { - ListFolders { - api_builder: ApiBuilder::new() - .set_request(Method::from_bytes(b"MKCOL").unwrap(), url), + pub fn new() -> Self { + CreateFolder { + api_builder: ApiBuilder::new(), } } + pub fn set_url(&mut self, url: &str) -> &mut CreateFolder { + self.api_builder.build_request(Method::from_bytes(b"MKCOL").unwrap(), url); + self + } + pub async fn send(&mut self) -> Result { self.api_builder.send().await } - pub async fn send_with_err(mut self) -> Result<(), ApiError> { - let res = self.send().await.map_err(ApiError::RequestError)?; + pub fn send_with_err(&mut self) -> Result<(), ApiError> { + let res = tokio::runtime::Runtime::new().unwrap().block_on(async { + self.send().await + }).map_err(ApiError::RequestError)?; if res.status().is_success() { - Ok() + Ok(()) } else { Err(ApiError::IncorrectRequest(res)) }