1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! Offline / missing media detection for clips.
//!
//! [`ClipOfflineDetector`] checks whether the media file associated with a
//! clip is accessible on the local filesystem. A clip is considered
//! **online** when its media path exists as a regular file; it is considered
//! **offline** (missing) otherwise.
//!
//! # Example
//!
//! ```no_run
//! use oximedia_clips::offline::ClipOfflineDetector;
//!
//! // Returns true if the file exists at the given path.
//! let is_online = ClipOfflineDetector::check(42, "/media/footage/shot001.mov");
//! println!("clip 42 online: {is_online}");
//! ```
#![allow(dead_code)]
use std::path::Path;
// ─────────────────────────────────────────────────────────────────────────────
// ClipOfflineDetector
// ─────────────────────────────────────────────────────────────────────────────
/// Stateless helper that checks whether clip media files are accessible.
pub struct ClipOfflineDetector;
impl ClipOfflineDetector {
/// Check whether the media for `clip_id` is available at `media_path`.
///
/// Returns `true` when `media_path` points to an existing file (the clip
/// is **online**), `false` when the file is missing or the path is a
/// directory (the clip is **offline**).
///
/// The `clip_id` parameter is accepted for API consistency and logging but
/// is not used in the filesystem check itself.
pub fn check(_clip_id: u64, media_path: &str) -> bool {
let path = Path::new(media_path);
path.exists() && path.is_file()
}
/// Check a list of `(clip_id, media_path)` pairs and return only the IDs
/// of clips whose media is offline (missing).
pub fn offline_clips(pairs: &[(u64, &str)]) -> Vec<u64> {
pairs
.iter()
.filter_map(|(id, path)| {
if !Self::check(*id, path) {
Some(*id)
} else {
None
}
})
.collect()
}
/// Return `true` when all supplied clips are online.
pub fn all_online(pairs: &[(u64, &str)]) -> bool {
Self::offline_clips(pairs).is_empty()
}
}
// ─────────────────────────────────────────────────────────────────────────────
// Tests
// ─────────────────────────────────────────────────────────────────────────────
#[cfg(test)]
mod tests {
use super::*;
use std::io::Write;
/// Create a temporary file in `std::env::temp_dir()` and return its path.
fn create_temp_file(name: &str) -> String {
let mut path = std::env::temp_dir();
path.push(name);
let mut f = std::fs::File::create(&path).expect("create temp file");
f.write_all(b"oximedia test").expect("write temp content");
path.to_str().expect("path str").to_string()
}
#[test]
fn test_check_existing_file_returns_true() {
let path = create_temp_file("oximedia_offline_test_a.tmp");
assert!(ClipOfflineDetector::check(1, &path));
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_check_missing_file_returns_false() {
let path = {
let mut p = std::env::temp_dir();
p.push("oximedia_does_not_exist_12345_offline.mov");
p.to_str().expect("path str").to_string()
};
// Make sure it doesn't exist.
let _ = std::fs::remove_file(&path);
assert!(!ClipOfflineDetector::check(2, &path));
}
#[test]
fn test_check_directory_returns_false() {
let dir = std::env::temp_dir();
let dir_str = dir.to_str().expect("path str");
assert!(!ClipOfflineDetector::check(3, dir_str));
}
#[test]
fn test_offline_clips_empty_when_all_online() {
let path = create_temp_file("oximedia_offline_test_b.tmp");
let pairs = vec![(10u64, path.as_str())];
let offline = ClipOfflineDetector::offline_clips(&pairs);
assert!(offline.is_empty());
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_offline_clips_detects_missing() {
let missing = {
let mut p = std::env::temp_dir();
p.push("oximedia_missing_clip_xyz_offline.mov");
// Ensure it does not exist.
let _ = std::fs::remove_file(&p);
p.to_str().expect("path str").to_string()
};
let pairs = vec![(42u64, missing.as_str())];
let offline = ClipOfflineDetector::offline_clips(&pairs);
assert_eq!(offline, vec![42]);
}
#[test]
fn test_all_online_true_when_all_files_exist() {
let path = create_temp_file("oximedia_offline_test_c.tmp");
let pairs = vec![(1u64, path.as_str())];
assert!(ClipOfflineDetector::all_online(&pairs));
let _ = std::fs::remove_file(&path);
}
#[test]
fn test_all_online_false_when_some_missing() {
let path = create_temp_file("oximedia_offline_test_d.tmp");
let missing = {
let mut p = std::env::temp_dir();
p.push("oximedia_definitely_missing_abc_offline.mov");
let _ = std::fs::remove_file(&p);
p.to_str().expect("path str").to_string()
};
let pairs = vec![(1u64, path.as_str()), (2u64, missing.as_str())];
assert!(!ClipOfflineDetector::all_online(&pairs));
let _ = std::fs::remove_file(&path);
}
}