use std::path::PathBuf;
use std::time::SystemTime;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FileEvent {
Modified(PathBuf),
Deleted(PathBuf),
Renamed(PathBuf, PathBuf),
}
impl FileEvent {
pub fn path(&self) -> &PathBuf {
match self {
FileEvent::Modified(path) => path,
FileEvent::Deleted(path) => path,
FileEvent::Renamed(_, new_path) => new_path,
}
}
pub fn paths(&self) -> Vec<&PathBuf> {
match self {
FileEvent::Modified(path) => vec![path],
FileEvent::Deleted(path) => vec![path],
FileEvent::Renamed(old, new) => vec![old, new],
}
}
}
pub type WorktreeId = String;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EventType {
Modified,
Deleted,
Renamed,
}
#[derive(Debug, Clone)]
pub struct IndexingEvent {
pub worktree_id: WorktreeId,
pub path: PathBuf,
pub event_type: EventType,
pub timestamp: SystemTime,
pub old_path: Option<PathBuf>,
}
impl IndexingEvent {
pub fn from_file_event(
worktree_id: WorktreeId,
file_event: FileEvent,
timestamp: SystemTime,
) -> Self {
match file_event {
FileEvent::Modified(path) => IndexingEvent {
worktree_id,
path,
event_type: EventType::Modified,
timestamp,
old_path: None,
},
FileEvent::Deleted(path) => IndexingEvent {
worktree_id,
path,
event_type: EventType::Deleted,
timestamp,
old_path: None,
},
FileEvent::Renamed(old_path, new_path) => IndexingEvent {
worktree_id,
path: new_path,
event_type: EventType::Renamed,
timestamp,
old_path: Some(old_path),
},
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::PathBuf;
#[test]
fn test_modified_event() {
let path = PathBuf::from("/test/file.txt");
let event = FileEvent::Modified(path.clone());
assert_eq!(event.path(), &path);
assert_eq!(event.paths(), vec![&path]);
}
#[test]
fn test_deleted_event() {
let path = PathBuf::from("/test/file.txt");
let event = FileEvent::Deleted(path.clone());
assert_eq!(event.path(), &path);
assert_eq!(event.paths(), vec![&path]);
}
#[test]
fn test_renamed_event() {
let old_path = PathBuf::from("/test/old.txt");
let new_path = PathBuf::from("/test/new.txt");
let event = FileEvent::Renamed(old_path.clone(), new_path.clone());
assert_eq!(event.path(), &new_path);
assert_eq!(event.paths(), vec![&old_path, &new_path]);
}
#[test]
fn test_indexing_event_from_modified() {
let path = PathBuf::from("/test/file.txt");
let file_event = FileEvent::Modified(path.clone());
let timestamp = SystemTime::now();
let worktree_id = "worktree-1".to_string();
let indexing_event =
IndexingEvent::from_file_event(worktree_id.clone(), file_event, timestamp);
assert_eq!(indexing_event.worktree_id, worktree_id);
assert_eq!(indexing_event.path, path);
assert_eq!(indexing_event.event_type, EventType::Modified);
assert_eq!(indexing_event.timestamp, timestamp);
assert_eq!(indexing_event.old_path, None);
}
#[test]
fn test_indexing_event_from_deleted() {
let path = PathBuf::from("/test/file.txt");
let file_event = FileEvent::Deleted(path.clone());
let timestamp = SystemTime::now();
let worktree_id = "worktree-2".to_string();
let indexing_event =
IndexingEvent::from_file_event(worktree_id.clone(), file_event, timestamp);
assert_eq!(indexing_event.worktree_id, worktree_id);
assert_eq!(indexing_event.path, path);
assert_eq!(indexing_event.event_type, EventType::Deleted);
assert_eq!(indexing_event.timestamp, timestamp);
assert_eq!(indexing_event.old_path, None);
}
#[test]
fn test_indexing_event_from_renamed() {
let old_path = PathBuf::from("/test/old.txt");
let new_path = PathBuf::from("/test/new.txt");
let file_event = FileEvent::Renamed(old_path.clone(), new_path.clone());
let timestamp = SystemTime::now();
let worktree_id = "worktree-3".to_string();
let indexing_event =
IndexingEvent::from_file_event(worktree_id.clone(), file_event, timestamp);
assert_eq!(indexing_event.worktree_id, worktree_id);
assert_eq!(indexing_event.path, new_path);
assert_eq!(indexing_event.event_type, EventType::Renamed);
assert_eq!(indexing_event.timestamp, timestamp);
assert_eq!(indexing_event.old_path, Some(old_path));
}
}