opendal/services/webhdfs/
message.rs1use serde::Deserialize;
21
22#[derive(Debug, Deserialize)]
23pub(super) struct BooleanResp {
24 pub boolean: bool,
25}
26
27#[derive(Debug, Deserialize)]
28#[serde(rename_all = "PascalCase")]
29pub(super) struct FileStatusWrapper {
30 pub file_status: FileStatus,
31}
32
33#[derive(Debug, Deserialize)]
34#[serde(rename_all = "PascalCase")]
35pub(super) struct FileStatusesWrapper {
36 pub file_statuses: FileStatuses,
37}
38
39#[derive(Debug, Deserialize)]
40#[serde(rename_all = "PascalCase")]
41pub(super) struct DirectoryListingWrapper {
42 pub directory_listing: DirectoryListing,
43}
44
45#[derive(Debug, Default, Deserialize)]
46#[serde(rename_all = "camelCase")]
47pub(super) struct DirectoryListing {
48 pub partial_listing: PartialListing,
49 pub remaining_entries: u32,
50}
51
52#[derive(Debug, Default, Deserialize)]
53#[serde(rename_all = "PascalCase")]
54pub(super) struct PartialListing {
55 pub file_statuses: FileStatuses,
56}
57
58#[derive(Debug, Default, Deserialize)]
59#[serde(rename_all = "PascalCase")]
60pub(super) struct FileStatuses {
61 pub file_status: Vec<FileStatus>,
62}
63
64#[derive(Debug, Default, Deserialize)]
65#[serde(rename_all = "camelCase")]
66pub struct FileStatus {
67 pub length: u64,
68 pub modification_time: i64,
69
70 pub path_suffix: String,
71 #[serde(rename = "type")]
72 pub ty: FileStatusType,
73}
74
75#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
76#[serde(rename_all = "UPPERCASE")]
77pub enum FileStatusType {
78 Directory,
79 #[default]
80 File,
81}
82
83#[cfg(test)]
84mod test {
85 use super::*;
86
87 #[test]
88 fn test_file_status() {
89 let json = r#"
90{
91 "FileStatus":
92 {
93 "accessTime" : 0,
94 "blockSize" : 0,
95 "group" : "supergroup",
96 "length" : 0,
97 "modificationTime": 1320173277227,
98 "owner" : "webuser",
99 "pathSuffix" : "",
100 "permission" : "777",
101 "replication" : 0,
102 "type" : "DIRECTORY"
103 }
104}
105"#;
106 let status: FileStatusWrapper = serde_json::from_str(json).expect("must success");
107 assert_eq!(status.file_status.length, 0);
108 assert_eq!(status.file_status.modification_time, 1320173277227);
109 assert_eq!(status.file_status.path_suffix, "");
110 assert_eq!(status.file_status.ty, FileStatusType::Directory);
111 }
112
113 #[tokio::test]
114 async fn test_list_empty() {
115 let json = r#"
116 {
117 "FileStatuses": {"FileStatus":[]}
118 }
119 "#;
120 let file_statuses = serde_json::from_str::<FileStatusesWrapper>(json)
121 .expect("must success")
122 .file_statuses
123 .file_status;
124 assert!(file_statuses.is_empty());
125 }
126
127 #[tokio::test]
128 async fn test_list_status() {
129 let json = r#"
130{
131 "FileStatuses":
132 {
133 "FileStatus":
134 [
135 {
136 "accessTime" : 1320171722771,
137 "blockSize" : 33554432,
138 "group" : "supergroup",
139 "length" : 24930,
140 "modificationTime": 1320171722771,
141 "owner" : "webuser",
142 "pathSuffix" : "a.patch",
143 "permission" : "644",
144 "replication" : 1,
145 "type" : "FILE"
146 },
147 {
148 "accessTime" : 0,
149 "blockSize" : 0,
150 "group" : "supergroup",
151 "length" : 0,
152 "modificationTime": 1320895981256,
153 "owner" : "szetszwo",
154 "pathSuffix" : "bar",
155 "permission" : "711",
156 "replication" : 0,
157 "type" : "DIRECTORY"
158 }
159 ]
160 }
161}
162 "#;
163
164 let file_statuses = serde_json::from_str::<FileStatusesWrapper>(json)
165 .expect("must success")
166 .file_statuses
167 .file_status;
168
169 assert_eq!(file_statuses.len(), 2);
171 assert_eq!(file_statuses[0].length, 24930);
172 assert_eq!(file_statuses[0].modification_time, 1320171722771);
173 assert_eq!(file_statuses[0].path_suffix, "a.patch");
174 assert_eq!(file_statuses[0].ty, FileStatusType::File);
175 assert_eq!(file_statuses[1].length, 0);
176 assert_eq!(file_statuses[1].modification_time, 1320895981256);
177 assert_eq!(file_statuses[1].path_suffix, "bar");
178 assert_eq!(file_statuses[1].ty, FileStatusType::Directory);
179 }
180
181 #[tokio::test]
182 async fn test_list_status_batch() {
183 let json = r#"
184{
185 "DirectoryListing": {
186 "partialListing": {
187 "FileStatuses": {
188 "FileStatus": [
189 {
190 "accessTime": 0,
191 "blockSize": 0,
192 "childrenNum": 0,
193 "fileId": 16387,
194 "group": "supergroup",
195 "length": 0,
196 "modificationTime": 1473305882563,
197 "owner": "andrew",
198 "pathSuffix": "bardir",
199 "permission": "755",
200 "replication": 0,
201 "storagePolicy": 0,
202 "type": "DIRECTORY"
203 },
204 {
205 "accessTime": 1473305896945,
206 "blockSize": 1024,
207 "childrenNum": 0,
208 "fileId": 16388,
209 "group": "supergroup",
210 "length": 0,
211 "modificationTime": 1473305896965,
212 "owner": "andrew",
213 "pathSuffix": "bazfile",
214 "permission": "644",
215 "replication": 3,
216 "storagePolicy": 0,
217 "type": "FILE"
218 }
219 ]
220 }
221 },
222 "remainingEntries": 2
223 }
224}
225 "#;
226
227 let directory_listing = serde_json::from_str::<DirectoryListingWrapper>(json)
228 .expect("must success")
229 .directory_listing;
230
231 assert_eq!(directory_listing.remaining_entries, 2);
232 assert_eq!(
233 directory_listing
234 .partial_listing
235 .file_statuses
236 .file_status
237 .len(),
238 2
239 );
240 assert_eq!(
241 directory_listing.partial_listing.file_statuses.file_status[0].path_suffix,
242 "bardir"
243 );
244 assert_eq!(
245 directory_listing.partial_listing.file_statuses.file_status[1].path_suffix,
246 "bazfile"
247 );
248 }
249}