most done.
This commit is contained in:
76
src/meta/tree.rs
Normal file
76
src/meta/tree.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::file::FileMeta;
|
||||
use crate::constants::META_VERSION;
|
||||
use crate::utils::{basename, should_skip_dir, should_skip_file};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DirSnapshot {
|
||||
pub dir_name: String,
|
||||
pub dirs: Vec<DirSnapshot>,
|
||||
pub files: Vec<FileMeta>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub v: Option<String>,
|
||||
}
|
||||
|
||||
impl DirSnapshot {
|
||||
pub fn build_root(path: &Path) -> Result<Self> {
|
||||
let mut node = Self::build_node(path)?;
|
||||
node.v = Some(META_VERSION.to_string());
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
fn build_node(path: &Path) -> Result<Self> {
|
||||
let dir_name = path
|
||||
.file_name()
|
||||
.map(basename)
|
||||
.unwrap_or_else(|| path.to_string_lossy().to_string());
|
||||
|
||||
let mut dirs = Vec::new();
|
||||
let mut files = Vec::new();
|
||||
|
||||
let mut entries = fs::read_dir(path)
|
||||
.with_context(|| format!("无法遍历目录: {}", path.display()))?
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.with_context(|| format!("读取目录失败: {}", path.display()))?;
|
||||
|
||||
entries.sort_by(|a, b| a.file_name().cmp(&b.file_name()));
|
||||
|
||||
for entry in entries {
|
||||
let file_name = entry.file_name();
|
||||
let name = file_name.to_string_lossy().to_string();
|
||||
let full_path = entry.path();
|
||||
let file_type = entry
|
||||
.file_type()
|
||||
.with_context(|| format!("无法读取类型: {}", full_path.display()))?;
|
||||
|
||||
if file_type.is_dir() {
|
||||
if should_skip_dir(&name) {
|
||||
continue;
|
||||
}
|
||||
println!("目录: {}", full_path.display());
|
||||
dirs.push(Self::build_node(&full_path)?);
|
||||
continue;
|
||||
}
|
||||
|
||||
if should_skip_file(&name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let meta = FileMeta::from_path(&full_path)?;
|
||||
println!("文件: {} {}", meta.friendly_size, full_path.display());
|
||||
files.push(meta);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
dir_name,
|
||||
dirs,
|
||||
files,
|
||||
v: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user