opendal/services/etcd/
lister.rs1use std::sync::Arc;
19use std::vec::IntoIter;
20
21use super::core::EtcdCore;
22use crate::raw::oio::Entry;
23use crate::raw::{build_abs_path, build_rel_path, oio};
24use crate::*;
25
26pub struct EtcdLister {
27 root: String,
28 path: String,
29 iter: IntoIter<String>,
30}
31
32impl EtcdLister {
33 pub async fn new(core: Arc<EtcdCore>, root: String, path: String) -> Result<Self> {
34 let abs_path = build_abs_path(&root, &path);
35
36 let mut client = core.conn().await?;
38 let get_options = Some(
39 etcd_client::GetOptions::new()
40 .with_prefix()
41 .with_keys_only(),
42 );
43 let resp = client
44 .get(abs_path.as_str(), get_options)
45 .await
46 .map_err(super::error::format_etcd_error)?;
47
48 let mut keys = Vec::new();
50 for kv in resp.kvs() {
51 let key = kv.key_str().map(String::from).map_err(|err| {
52 Error::new(ErrorKind::Unexpected, "store key is not valid utf-8 string")
53 .set_source(err)
54 })?;
55 keys.push(key);
56 }
57
58 Ok(Self {
59 root,
60 path: abs_path,
61 iter: keys.into_iter(),
62 })
63 }
64}
65
66impl oio::List for EtcdLister {
67 async fn next(&mut self) -> Result<Option<Entry>> {
68 for key in self.iter.by_ref() {
69 if key.starts_with(&self.path) {
70 let path = build_rel_path(&self.root, &key);
71
72 let entry = Entry::new(&path, Metadata::new(EntryMode::from_path(&key)));
73 return Ok(Some(entry));
74 }
75 }
76
77 Ok(None)
78 }
79}