diff --git a/src/archiver/archiver_impl.rs b/src/archiver/archiver_impl.rs index 258713c..2ad7500 100644 --- a/src/archiver/archiver_impl.rs +++ b/src/archiver/archiver_impl.rs @@ -1,4 +1,3 @@ -use std::io::Read; use std::path::{Path, PathBuf}; use anyhow::Result; @@ -7,11 +6,11 @@ use indicatif::ProgressBar; use log::*; use crate::backend::{DecryptWriteBackend, ReadSource, ReadSourceEntry}; -use crate::blob::{BlobType, Node}; +use crate::blob::BlobType; use crate::index::{IndexedBackend, Indexer, SharedIndexer}; use crate::repofile::{ConfigFile, SnapshotFile}; -use super::{FileArchiver, Parent, ParentResult, TreeArchiver, TreeIterator}; +use super::{FileArchiver, Parent, TreeArchiver, TreeIterator}; pub struct Archiver { file_archiver: FileArchiver, @@ -53,6 +52,13 @@ impl Archiver { as_path: Option<&PathBuf>, p: &ProgressBar, ) -> Result { + if !p.is_hidden() { + if let Some(size) = src.size()? { + p.set_length(size); + } + }; + p.set_prefix("backing up..."); + // filter out errors and handle as_path let iter = src.entries().filter_map(|item| match item { Err(e) => { @@ -108,22 +114,10 @@ impl Archiver { } let snap = self.finalize_snapshot()?; + p.finish_with_message("done"); Ok(snap) } - pub fn backup_reader( - &mut self, - path: &Path, - r: impl Read + Send + 'static, - node: Node, - parent: ParentResult<()>, - p: ProgressBar, - ) -> Result<()> { - let (node, filesize) = self.file_archiver.backup_reader(r, node, p)?; - self.tree_archiver.add_file(path, node, parent, filesize); - Ok(()) - } - pub fn finalize_snapshot(mut self) -> Result { let stats = self.file_archiver.finalize()?; let (id, mut summary) = self.tree_archiver.finalize()?; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index b00858b..7aebcbb 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -17,6 +17,7 @@ pub mod local; pub mod node; pub mod rclone; pub mod rest; +pub mod stdin; pub use self::ignore::*; pub use cache::*; @@ -28,6 +29,7 @@ pub use local::*; use node::Node; pub use rclone::*; pub use rest::*; +pub use stdin::*; /// All [`FileType`]s which are located in separated directories pub const ALL_FILE_TYPES: [FileType; 4] = [ diff --git a/src/backend/stdin.rs b/src/backend/stdin.rs new file mode 100644 index 0000000..d35cc04 --- /dev/null +++ b/src/backend/stdin.rs @@ -0,0 +1,63 @@ +use std::io::{stdin, Stdin}; +use std::path::Path; + +use anyhow::Result; + +use super::{node::Metadata, node::NodeType, Node, ReadSource}; +use super::{ReadSourceEntry, ReadSourceOpen}; + +pub struct StdinSource { + finished: bool, +} + +impl StdinSource { + pub fn new() -> Result { + Ok(Self { finished: false }) + } +} + +pub struct OpenStdin(); + +impl ReadSourceOpen for OpenStdin { + type Reader = Stdin; + + fn open(self) -> Result { + Ok(stdin()) + } +} + +impl ReadSource for StdinSource { + type Open = OpenStdin; + type Iter = Self; + + fn size(&self) -> Result> { + Ok(None) + } + + fn entries(self) -> Self::Iter { + self + } +} + +impl Iterator for StdinSource { + type Item = Result>; + + fn next(&mut self) -> Option { + if self.finished { + return None; + } + self.finished = true; + + Some(Ok(ReadSourceEntry { + path: Path::new("stdin").to_path_buf(), + node: Node::new( + "stdin".to_string(), + NodeType::File, + Metadata::default(), + None, + None, + ), + open: Some(OpenStdin()), + })) + } +} diff --git a/src/commands/backup.rs b/src/commands/backup.rs index 73ea623..bc8ed1e 100644 --- a/src/commands/backup.rs +++ b/src/commands/backup.rs @@ -11,9 +11,8 @@ use serde::Deserialize; use toml::Value; use super::{bytes, progress_bytes, progress_counter, RusticConfig}; -use crate::archiver::{Archiver, Parent, ParentResult}; -use crate::backend::{DryRunBackend, LocalSource, LocalSourceOptions, ReadSource}; -use crate::blob::{Metadata, Node, NodeType}; +use crate::archiver::{Archiver, Parent}; +use crate::backend::{DryRunBackend, LocalSource, LocalSourceOptions, StdinSource}; use crate::index::IndexBackend; use crate::repofile::{ PathList, SnapshotFile, SnapshotGroup, SnapshotGroupCriterion, SnapshotOptions, @@ -209,40 +208,15 @@ pub(super) fn execute( let parent = Parent::new(&index, parent_tree, opts.ignore_ctime, opts.ignore_inode); - let snap = if backup_stdin { - let mut archiver = Archiver::new(be, index, &repo.config, parent, snap)?; - let p = progress_bytes("starting backup from stdin..."); - archiver.backup_reader( - &PathBuf::new(), - std::io::stdin(), - Node::new( - opts.stdin_filename, - NodeType::File, - Metadata::default(), - None, - None, - ), - ParentResult::NotFound, - p.clone(), - )?; + let archiver = Archiver::new(be, index, &repo.config, parent, snap)?; + let p = progress_bytes("determining size..."); - let snap = archiver.finalize_snapshot()?; - p.finish_with_message("done"); - snap + let snap = if backup_stdin { + let src = StdinSource::new()?; + archiver.archive(src, &backup_path[0], as_path.as_ref(), &p)? } else { let src = LocalSource::new(opts.ignore_opts.clone(), &backup_path)?; - - let p = progress_bytes("determining size..."); - if !p.is_hidden() { - if let Some(size) = src.size()? { - p.set_length(size); - } - }; - p.set_prefix("backing up..."); - let archiver = Archiver::new(be, index.clone(), &repo.config, parent, snap)?; - let snap = archiver.archive(src, &backup_path[0], as_path.as_ref(), &p)?; - p.finish_with_message("done"); - snap + archiver.archive(src, &backup_path[0], as_path.as_ref(), &p)? }; if opts.json {