Skip to main content

nextcloud_trashbin/
item.rs

1//! Domain model representing a deleted item in Nextcloud's trashbin.
2
3use std::fmt;
4
5/// A deleted item in a user's Nextcloud trashbin.
6///
7/// Returned by [`TrashClient::list`](crate::TrashClient::list). Holds the
8/// metadata reported by Nextcloud's WebDAV trashbin endpoint, including its
9/// identifier, original filename, original location, deletion timestamp,
10/// and WebDAV properties.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct TrashItem {
13    /// Identifier of the trash item (the path segment in the trashbin URL).
14    pub id: String,
15    /// WebDAV resource href reported by the server.
16    pub href: String,
17    /// Original file or directory name before deletion (`trashbin-filename`).
18    pub filename: String,
19    /// Path where the item resided before deletion (`trashbin-original-location`).
20    pub original_location: String,
21    /// Unix timestamp (in seconds) when the item was moved to the trash (`trashbin-deletion-time`).
22    pub deletion_time: Option<u64>,
23    /// Last modified time as reported by the server (`d:getlastmodified`).
24    pub last_modified: Option<String>,
25    /// Whether the resource is a collection/folder (`<d:collection/>`).
26    pub is_collection: bool,
27}
28
29impl TrashItem {
30    /// Identifier of the trash item.
31    pub fn id(&self) -> &str {
32        &self.id
33    }
34
35    /// WebDAV href of the item.
36    pub fn href(&self) -> &str {
37        &self.href
38    }
39
40    /// Original filename before deletion.
41    pub fn filename(&self) -> &str {
42        &self.filename
43    }
44
45    /// Original filename before deletion (alias for [`filename`](Self::filename)).
46    pub fn original_filename(&self) -> &str {
47        &self.filename
48    }
49
50    /// Original path where the item resided before deletion.
51    pub fn original_location(&self) -> &str {
52        &self.original_location
53    }
54
55    /// Unix timestamp when the item was deleted, if available.
56    pub fn deletion_time(&self) -> Option<u64> {
57        self.deletion_time
58    }
59
60    /// Last modified HTTP date string, if available.
61    pub fn last_modified(&self) -> Option<&str> {
62        self.last_modified.as_deref()
63    }
64
65    /// Whether the item is a collection (folder).
66    pub fn is_collection(&self) -> bool {
67        self.is_collection
68    }
69}
70
71impl fmt::Display for TrashItem {
72    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73        let kind = if self.is_collection {
74            "collection"
75        } else {
76            "file"
77        };
78        write!(f, "{kind} {} (id: {})", self.filename, self.id)
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::TrashItem;
85
86    #[test]
87    fn item_accessors_and_display() {
88        let item = TrashItem {
89            id: "report.pdf.d1609459200".to_owned(),
90            href: "/remote.php/dav/trashbin/alice/trash/report.pdf.d1609459200".to_owned(),
91            filename: "report.pdf".to_owned(),
92            original_location: "Documents/report.pdf".to_owned(),
93            deletion_time: Some(1609459200),
94            last_modified: Some("Fri, 01 Jan 2021 00:00:00 GMT".to_owned()),
95            is_collection: false,
96        };
97
98        assert_eq!(item.id(), "report.pdf.d1609459200");
99        assert_eq!(
100            item.href(),
101            "/remote.php/dav/trashbin/alice/trash/report.pdf.d1609459200"
102        );
103        assert_eq!(item.filename(), "report.pdf");
104        assert_eq!(item.original_filename(), "report.pdf");
105        assert_eq!(item.original_location(), "Documents/report.pdf");
106        assert_eq!(item.deletion_time(), Some(1609459200));
107        assert_eq!(item.last_modified(), Some("Fri, 01 Jan 2021 00:00:00 GMT"));
108        assert!(!item.is_collection());
109
110        let rendered = item.to_string();
111        assert_eq!(rendered, "file report.pdf (id: report.pdf.d1609459200)");
112
113        let dir = TrashItem {
114            id: "Photos.d1609459300".to_owned(),
115            href: "/remote.php/dav/trashbin/alice/trash/Photos.d1609459300/".to_owned(),
116            filename: "Photos".to_owned(),
117            original_location: "Photos".to_owned(),
118            deletion_time: None,
119            last_modified: None,
120            is_collection: true,
121        };
122        assert!(dir.is_collection());
123        assert_eq!(
124            dir.to_string(),
125            "collection Photos (id: Photos.d1609459300)"
126        );
127    }
128}