dav_server_opendalfs/
dir.rs1use super::metadata::OpendalMetaData;
19use super::utils::*;
20use dav_server::fs::{DavDirEntry, DavMetaData, FsResult};
21use futures::StreamExt;
22use futures::{FutureExt, Stream};
23use opendal::raw::normalize_path;
24use opendal::Operator;
25use opendal::{Entry, Lister};
26use std::pin::Pin;
27use std::task::Poll::Ready;
28use std::task::{ready, Context, Poll};
29
30pub struct OpendalStream {
32 op: Operator,
33 lister: Lister,
34 path: String,
35}
36
37impl OpendalStream {
38 pub fn new(op: Operator, lister: Lister, p: &str) -> Self {
40 OpendalStream {
41 op,
42 lister,
43 path: normalize_path(p),
44 }
45 }
46}
47
48impl Stream for OpendalStream {
49 type Item = FsResult<Box<dyn DavDirEntry>>;
50
51 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
52 let dav_stream = self.get_mut();
53 loop {
54 match ready!(dav_stream.lister.poll_next_unpin(cx)) {
55 Some(entry) => {
56 let entry = entry.map_err(convert_error)?;
57 if entry.path() == dav_stream.path {
58 continue;
59 }
60 let webdav_entry = OpendalDirEntry::new(dav_stream.op.clone(), entry);
61 return Ready(Some(Ok(Box::new(webdav_entry) as Box<dyn DavDirEntry>)));
62 }
63 None => return Ready(None),
64 }
65 }
66 }
67}
68
69pub struct OpendalDirEntry {
71 op: Operator,
72 dir_entry: Entry,
73}
74
75impl OpendalDirEntry {
76 pub fn new(op: Operator, dir_entry: Entry) -> Self {
78 OpendalDirEntry { dir_entry, op }
79 }
80}
81
82impl DavDirEntry for OpendalDirEntry {
83 fn name(&self) -> Vec<u8> {
84 self.dir_entry.name().as_bytes().to_vec()
85 }
86
87 fn metadata(&self) -> dav_server::fs::FsFuture<Box<dyn DavMetaData>> {
88 async move {
89 self.op
90 .stat(self.dir_entry.path())
91 .await
92 .map(|metadata| Box::new(OpendalMetaData::new(metadata)) as Box<dyn DavMetaData>)
93 .map_err(convert_error)
94 }
95 .boxed()
96 }
97}