mirror of
https://github.com/rustic-rs/rustic.git
synced 2025-10-26 11:18:51 +00:00
impl ReadSource for stdin
This commit is contained in:
parent
8ca3a99ab2
commit
f4896e7e57
@ -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<BE: DecryptWriteBackend, I: IndexedBackend> {
|
||||
file_archiver: FileArchiver<BE, I>,
|
||||
@ -53,6 +52,13 @@ impl<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
|
||||
as_path: Option<&PathBuf>,
|
||||
p: &ProgressBar,
|
||||
) -> Result<SnapshotFile> {
|
||||
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<BE: DecryptWriteBackend, I: IndexedBackend> Archiver<BE, I> {
|
||||
}
|
||||
|
||||
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<SnapshotFile> {
|
||||
let stats = self.file_archiver.finalize()?;
|
||||
let (id, mut summary) = self.tree_archiver.finalize()?;
|
||||
|
||||
@ -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] = [
|
||||
|
||||
63
src/backend/stdin.rs
Normal file
63
src/backend/stdin.rs
Normal file
@ -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<Self> {
|
||||
Ok(Self { finished: false })
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpenStdin();
|
||||
|
||||
impl ReadSourceOpen for OpenStdin {
|
||||
type Reader = Stdin;
|
||||
|
||||
fn open(self) -> Result<Self::Reader> {
|
||||
Ok(stdin())
|
||||
}
|
||||
}
|
||||
|
||||
impl ReadSource for StdinSource {
|
||||
type Open = OpenStdin;
|
||||
type Iter = Self;
|
||||
|
||||
fn size(&self) -> Result<Option<u64>> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn entries(self) -> Self::Iter {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for StdinSource {
|
||||
type Item = Result<ReadSourceEntry<OpenStdin>>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
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()),
|
||||
}))
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user