opendal/blocking/
list.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use futures::StreamExt;
19
20use crate::Lister as AsyncLister;
21use crate::*;
22
23/// BlockingLister is designed to list entries at given path in a blocking
24/// manner.
25///
26/// Users can construct Lister by [`blocking::Operator::lister`] or [`blocking::Operator::lister_with`].
27///
28/// - Lister implements `Iterator<Item = Result<Entry>>`.
29/// - Lister will return `None` if there is no more entries or error has been returned.
30pub struct Lister {
31    handle: tokio::runtime::Handle,
32    lister: Option<AsyncLister>,
33}
34
35/// # Safety
36///
37/// BlockingLister will only be accessed by `&mut Self`
38unsafe impl Sync for Lister {}
39
40impl Lister {
41    /// Create a new lister.
42    pub(crate) fn new(handle: tokio::runtime::Handle, lister: AsyncLister) -> Self {
43        Self {
44            handle,
45            lister: Some(lister),
46        }
47    }
48}
49
50impl Iterator for Lister {
51    type Item = Result<Entry>;
52
53    fn next(&mut self) -> Option<Self::Item> {
54        let Some(lister) = self.lister.as_mut() else {
55            return Some(Err(Error::new(
56                ErrorKind::Unexpected,
57                "lister has been dropped",
58            )));
59        };
60
61        self.handle.block_on(lister.next())
62    }
63}
64
65impl Drop for Lister {
66    fn drop(&mut self) {
67        if let Some(v) = self.lister.take() {
68            self.handle.block_on(async move { drop(v) });
69        }
70    }
71}