phase 3
This commit is contained in:
@@ -90,6 +90,22 @@ The `validate` method should take `&self` and return `Result<(), DrawerError>`.
|
|||||||
creating a `DrawerOperation` and not using it, also call `validate` and print out the error if there is one. This means
|
creating a `DrawerOperation` and not using it, also call `validate` and print out the error if there is one. This means
|
||||||
we also need to `impl Display` on `DrawerError`.
|
we also need to `impl Display` on `DrawerError`.
|
||||||
|
|
||||||
|
### Phase 3
|
||||||
|
|
||||||
|
For phase 3 we want to start implementing the `close` command. We'll get the tar part working but not worry about encryption yet.
|
||||||
|
|
||||||
|
- Make a new method `perform` on `DrawerOperation` which takes `&self` and returns `Result<(), DrawerError>`.
|
||||||
|
- `perform` should first call `validate` and return the error if there is one.
|
||||||
|
- After that, it should call either `open(&self)` or `close(&self)` depending on the operation type. For now, `open` will just be a `todo!()`
|
||||||
|
- The new `close` method should create a vec<u8> consisting of the contents of the target directory as a tarball (use the tar create we depend on)
|
||||||
|
- After creating the vec, it should write it out to the drawer file path.
|
||||||
|
|
||||||
|
I'm going to add some test data to the project under `tests/` but it's just random data to test, ignore the contents of all those files.
|
||||||
|
|
||||||
|
### Phase 3a
|
||||||
|
|
||||||
|
As a minor improvement, make the `perform_close` method also gzip the contents of the tarball.
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ pub enum DrawerError {
|
|||||||
KeyInvalid(PathBuf),
|
KeyInvalid(PathBuf),
|
||||||
TargetNotEmpty(PathBuf),
|
TargetNotEmpty(PathBuf),
|
||||||
DrawerInsideTarget,
|
DrawerInsideTarget,
|
||||||
|
TarFailed,
|
||||||
|
WriteFailed(PathBuf),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for DrawerError {
|
impl fmt::Display for DrawerError {
|
||||||
@@ -24,6 +26,8 @@ impl fmt::Display for DrawerError {
|
|||||||
DrawerError::KeyInvalid(p) => write!(f, "key not found or not readable: {}", p.display()),
|
DrawerError::KeyInvalid(p) => write!(f, "key not found or not readable: {}", p.display()),
|
||||||
DrawerError::TargetNotEmpty(p) => write!(f, "target is not empty: {} (use -f to force)", p.display()),
|
DrawerError::TargetNotEmpty(p) => write!(f, "target is not empty: {} (use -f to force)", p.display()),
|
||||||
DrawerError::DrawerInsideTarget => write!(f, "drawer file is inside the target directory"),
|
DrawerError::DrawerInsideTarget => write!(f, "drawer file is inside the target directory"),
|
||||||
|
DrawerError::TarFailed => write!(f, "failed to create tarball"),
|
||||||
|
DrawerError::WriteFailed(p) => write!(f, "failed to write drawer file: {}", p.display()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ fn main() {
|
|||||||
match parse_args(std::env::args_os()) {
|
match parse_args(std::env::args_os()) {
|
||||||
Err(e) => eprintln!("{e}"),
|
Err(e) => eprintln!("{e}"),
|
||||||
Ok(op) => {
|
Ok(op) => {
|
||||||
if let Err(e) = op.validate() {
|
if let Err(e) = op.perform() {
|
||||||
eprintln!("{e}");
|
eprintln!("{e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-1
@@ -1,5 +1,4 @@
|
|||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::io;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use crate::error::DrawerError;
|
use crate::error::DrawerError;
|
||||||
@@ -94,6 +93,31 @@ fn resolve_key(key: Option<PathBuf>) -> KeyType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DrawerOperation {
|
impl DrawerOperation {
|
||||||
|
pub fn perform(&self) -> Result<(), DrawerError> {
|
||||||
|
self.validate()?;
|
||||||
|
match self.operation_type {
|
||||||
|
OperationType::Open => self.perform_open(),
|
||||||
|
OperationType::Close => self.perform_close(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perform_open(&self) -> Result<(), DrawerError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perform_close(&self) -> Result<(), DrawerError> {
|
||||||
|
let mut buf: Vec<u8> = Vec::new();
|
||||||
|
{
|
||||||
|
let mut archive = tar::Builder::new(&mut buf);
|
||||||
|
archive.append_dir_all(".", &self.target_path)
|
||||||
|
.map_err(|_| DrawerError::TarFailed)?;
|
||||||
|
archive.finish()
|
||||||
|
.map_err(|_| DrawerError::TarFailed)?;
|
||||||
|
}
|
||||||
|
std::fs::write(&self.drawer_file, &buf)
|
||||||
|
.map_err(|_| DrawerError::WriteFailed(self.drawer_file.clone()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate(&self) -> Result<(), DrawerError> {
|
pub fn validate(&self) -> Result<(), DrawerError> {
|
||||||
if self.drawer_file.extension().and_then(|e| e.to_str()) != Some("drawer") {
|
if self.drawer_file.extension().and_then(|e| e.to_str()) != Some("drawer") {
|
||||||
return Err(DrawerError::DrawerFileInvalidExtension(self.drawer_file.clone()));
|
return Err(DrawerError::DrawerFileInvalidExtension(self.drawer_file.clone()));
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Ignore this
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Ignore this too
|
||||||
Reference in New Issue
Block a user