1use std::{borrow::Cow, cmp::Ordering};
2
3use serde::ser::SerializeStruct;
4
5pub mod create;
6pub mod delete;
7pub mod list;
8pub mod movefolder;
9pub mod rename;
10
11pub const ROOT: u64 = 0;
12
13#[derive(Debug, serde::Deserialize)]
15pub(crate) struct FolderResponse {
16 pub metadata: Folder,
18}
19
20#[derive(Debug)]
22pub enum FolderIdentifier<'a> {
23 Path(Cow<'a, str>),
25
26 FolderId(u64),
28}
29
30impl<'a> FolderIdentifier<'a> {
31 #[inline]
33 pub fn path<P: Into<Cow<'a, str>>>(value: P) -> Self {
34 Self::Path(value.into())
35 }
36
37 #[inline]
39 pub fn folder_id(value: u64) -> Self {
40 Self::FolderId(value)
41 }
42}
43
44impl Default for FolderIdentifier<'_> {
45 fn default() -> Self {
46 Self::FolderId(0)
47 }
48}
49
50impl<'a> From<&'a str> for FolderIdentifier<'a> {
51 fn from(value: &'a str) -> Self {
52 Self::Path(Cow::Borrowed(value))
53 }
54}
55
56impl<'a> From<Cow<'a, str>> for FolderIdentifier<'a> {
57 fn from(value: Cow<'a, str>) -> Self {
58 Self::Path(value)
59 }
60}
61
62impl<'a> From<&'a String> for FolderIdentifier<'a> {
63 fn from(value: &'a String) -> Self {
64 Self::Path(Cow::Borrowed(value.as_str()))
65 }
66}
67
68impl From<String> for FolderIdentifier<'_> {
69 fn from(value: String) -> Self {
70 Self::Path(Cow::Owned(value))
71 }
72}
73
74impl From<u64> for FolderIdentifier<'_> {
75 fn from(value: u64) -> Self {
76 Self::FolderId(value)
77 }
78}
79
80impl serde::Serialize for FolderIdentifier<'_> {
81 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
82 where
83 S: serde::Serializer,
84 {
85 let mut builder = serializer.serialize_struct(stringify!(FolderIdentifier), 1)?;
86 match self {
87 Self::FolderId(folder_id) => {
88 builder.serialize_field("folderid", folder_id)?;
89 }
90 Self::Path(path) => {
91 builder.serialize_field("path", path)?;
92 }
93 }
94 builder.end()
95 }
96}
97
98#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
100pub struct Folder {
101 #[serde(flatten)]
103 pub base: crate::entry::EntryBase,
104
105 #[serde(rename = "folderid")]
107 pub folder_id: u64,
108
109 pub contents: Option<Vec<crate::entry::Entry>>,
111}
112
113impl Eq for Folder {}
114
115impl PartialEq for Folder {
116 fn eq(&self, other: &Self) -> bool {
117 self.base.id.eq(&other.base.id)
118 }
119}
120
121impl Ord for Folder {
122 fn cmp(&self, other: &Self) -> Ordering {
123 self.base.name.cmp(&other.base.name)
124 }
125}
126
127impl PartialOrd for Folder {
128 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
129 Some(self.cmp(other))
130 }
131}
132
133impl Folder {
134 pub fn find_entry(&self, name: &str) -> Option<&crate::entry::Entry> {
154 self.contents
155 .as_ref()
156 .and_then(|list| list.iter().find(|item| item.base().name == name))
157 }
158
159 pub fn find_file(&self, name: &str) -> Option<&crate::file::File> {
169 self.contents.as_ref().and_then(|list| {
170 list.iter()
171 .filter_map(|item| item.as_file())
172 .find(|item| item.base.name == name)
173 })
174 }
175
176 pub fn find_folder(&self, name: &str) -> Option<&Folder> {
186 self.contents.as_ref().and_then(|list| {
187 list.iter()
188 .filter_map(|item| item.as_folder())
189 .find(|item| item.base.name == name)
190 })
191 }
192}
193
194pub(crate) struct ToFolderIdentifier<'a>(pub FolderIdentifier<'a>);
196
197impl serde::Serialize for ToFolderIdentifier<'_> {
198 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: serde::Serializer,
201 {
202 let mut builder = serializer.serialize_struct(stringify!(FolderIdentifier), 1)?;
203 match self.0 {
204 FolderIdentifier::FolderId(ref folder_id) => {
205 builder.serialize_field("tofolderid", folder_id)?;
206 }
207 FolderIdentifier::Path(ref path) => {
208 builder.serialize_field("topath", path)?;
209 }
210 }
211 builder.end()
212 }
213}