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
use Path;
use crateResumeInfo;
const XATTR_RESUME_KEY: &str = "user.soar.resume";
/// Reads the `user.soar.resume` extended attribute from the given path and deserializes it into a `ResumeInfo`.
///
/// Returns `Some(ResumeInfo)` if the attribute exists and contains valid JSON; returns `None` if the attribute is missing, cannot be read, or fails to deserialize.
///
/// # Examples
///
/// ```
/// use soar_dl::xattr::read_resume;
///
/// // Attempt to read resume info from a file path.
/// if let Some(info) = read_resume("/path/to/file") {
/// let _ = info;
/// } else {
/// // no resume info available or it could not be parsed
/// }
/// ```
/// Writes the provided `ResumeInfo` into the file's extended attribute `user.soar.resume`.
///
/// Serializes `info` to JSON and stores the resulting bytes in the extended attribute for `path`.
///
/// # Returns
///
/// `Ok(())` on success, or an `std::io::Error` if serialization or the xattr write fails.
///
/// # Examples
///
/// ```no_run
/// use soar_dl::xattr::write_resume;
/// use soar_dl::types::ResumeInfo;
///
/// let info = ResumeInfo {
/// downloaded: 1024,
/// total: 10240,
/// etag: Some("etag-value".into()),
/// last_modified: None,
/// };
/// let path = std::path::Path::new("/tmp/download.partial");
/// write_resume(path, &info).unwrap();
/// ```
/// Removes the stored resume extended attribute from the given path.
///
/// Returns `Ok(())` if the attribute was removed successfully, or an `Err` with the I/O error encountered.
///
/// # Examples
///
/// ```no_run
/// use std::path::Path;
/// use soar_dl::xattr::remove_resume;
///
/// // Call with any path; result indicates whether the xattr removal succeeded.
/// let _ = remove_resume(Path::new("/tmp/some_file"));
/// ```