1use std::fs;
2use std::path::{Path, PathBuf};
3use std::time::SystemTime;
4use crate::{cli, config};
5use super::file_ops::compute_blake3_hash;
6use std::sync::Arc;
7
8#[derive(Debug, Clone)]
13pub struct FileInfo {
14 pub path: Arc<Path>,
16 pub mtime: SystemTime,
18 pub size: u64,
20 pub blake3_hash: Option<[u8; 32]>,
22}
23
24impl FileInfo {
25 pub fn from_path(path: &Path, compute_hash: bool) -> std::io::Result<Self> {
38 let metadata = fs::metadata(path)?;
39 let blake3_hash = if compute_hash && metadata.is_file() {
40 Some(compute_blake3_hash(path)?)
41 } else {
42 None
43 };
44 Ok(FileInfo {
45 path: Arc::from(path), mtime: metadata.modified()?,
47 size: metadata.len(),
48 blake3_hash,
49 })
50 }
51
52 pub fn is_newer_than(&self, target: &Self) -> bool {
60 self.mtime > target.mtime || self.size != target.size
61 }
62
63 pub fn content_eq(&self, other: &Self) -> bool {
74 self.size == other.size && self.blake3_hash == other.blake3_hash
75 }
76}
77
78#[derive(Debug, Clone)]
80pub struct SyncParameters {
81 pub source: PathBuf,
83 pub target: PathBuf,
85 pub dry_run: bool,
87 pub checksum: bool,
89 pub excludes: Vec<String>,
91 pub delete_extra: bool,
93 pub delete_excludes: Vec<String>,
95 pub detail: bool,
97}
98
99impl From<&cli::Command> for SyncParameters {
101 fn from(cmd: &cli::Command) -> Self {
102 match cmd {
103 cli::Command::Sync {
104 source,
105 target,
106 dry_run,
107 checksum,
108 delete,
109 exclude,
110 delete_exclude,
111 detail,
112 } => Self {
113 source: source.clone(),
114 target: target.clone(),
115 dry_run: *dry_run,
116 checksum: *checksum,
117 excludes: exclude.clone(),
118 delete_extra: *delete,
119 delete_excludes: delete_exclude.clone(),
120 detail: *detail,
121 },
122 cli::Command::Run {
123 name: _,
124 config: _,
125 dry_run,
126 checksum,
127 detail,
128 } => {
129 Self {
131 source: PathBuf::new(),
132 target: PathBuf::new(),
133 dry_run: *dry_run,
134 checksum: *checksum,
135 excludes: Vec::new(),
136 delete_extra: false,
137 delete_excludes: Vec::new(),
138 detail: *detail,
139 }
140 }
141 cli::Command::Watch {
142 name: _,
143 config: _,
144 delay: _,
145 checksum,
146 dry_run,
147 detail,
148 } => Self {
149 source: PathBuf::new(),
150 target: PathBuf::new(),
151 dry_run: *dry_run,
152 checksum: *checksum,
153 excludes: Vec::new(),
154 delete_extra: false,
155 delete_excludes: Vec::new(),
156 detail: *detail,
157 }
158 }
159 }
160}
161
162impl From<&config::SyncTask> for SyncParameters {
164 fn from(task: &config::SyncTask) -> Self {
165 Self {
166 source: task.source.clone(),
167 target: task.target.clone(),
168 dry_run: false, checksum: false, excludes: task.exclude.clone(),
171 delete_extra: task.delete_extra,
172 delete_excludes: task.delete_extra_exclude.clone(),
173 detail: false,
174 }
175 }
176}