Skip to main content

opendal_core/raw/oio/
entry.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 crate::*;
19
20/// Entry is returned by `Page` or `BlockingPage` during list operations.
21///
22/// # Notes
23///
24/// Differences between `crate::Entry` and `oio::Entry`:
25///
26/// - `crate::Entry` is the user's public API and have less public methods.
27/// - `oio::Entry` is the raw API and doesn't expose to users.
28#[derive(Debug, Clone)]
29pub struct Entry {
30    meta: Metadata,
31}
32
33impl PartialEq for Entry {
34    fn eq(&self, other: &Self) -> bool {
35        self.path() == other.path() && self.meta == other.meta
36    }
37}
38
39impl Eq for Entry {}
40
41impl Entry {
42    /// Create a new entry by its corresponding underlying storage.
43    ///
44    /// # Panics
45    ///
46    /// Panics when the compact metadata block containing `path` exceeds `u16::MAX` bytes.
47    pub fn new(path: &str, meta: Metadata) -> Entry {
48        Self::with(path.to_string(), meta)
49    }
50
51    /// Create a new entry with given value.
52    ///
53    /// # Panics
54    ///
55    /// Panics when the compact metadata block containing `path` exceeds `u16::MAX` bytes.
56    pub fn with(mut path: String, meta: Metadata) -> Entry {
57        // Normalize path as `/` if it's empty.
58        if path.is_empty() {
59            path = "/".to_string();
60        }
61
62        debug_assert!(
63            meta.mode().is_dir() == path.ends_with('/'),
64            "mode {:?} not match with path {}",
65            meta.mode(),
66            path
67        );
68
69        let mut builder = meta.into_builder();
70        builder.path(path);
71        Entry {
72            meta: builder.build(),
73        }
74    }
75
76    /// Set path for entry.
77    ///
78    /// # Panics
79    ///
80    /// Panics when the resulting compact metadata block exceeds `u16::MAX` bytes.
81    pub fn set_path(&mut self, path: &str) -> &mut Self {
82        let mut builder = self.meta.clone().into_builder();
83        builder.path(path);
84        self.meta = builder.build();
85        self
86    }
87
88    /// Get the path of entry.
89    pub fn path(&self) -> &str {
90        self.meta
91            .path()
92            .expect("listed entry metadata contains its path")
93    }
94
95    /// Get entry's mode.
96    pub fn mode(&self) -> EntryMode {
97        self.meta.mode()
98    }
99
100    /// Consume self to convert into an Entry.
101    ///
102    /// NOTE: implement this by hand to avoid leaking raw entry to end-users.
103    pub(crate) fn into_entry(self) -> crate::Entry {
104        crate::Entry::from_metadata(self.meta)
105    }
106
107    /// Get metadata of entry.
108    pub fn metadata(&self) -> &Metadata {
109        &self.meta
110    }
111
112    /// Consume this entry to get its path and metadata.
113    pub fn into_parts(self) -> (String, Metadata) {
114        (self.path().to_string(), self.meta)
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121
122    #[test]
123    fn entry_equality_includes_path() {
124        let metadata = MetadataBuilder::file(0).build();
125        assert_ne!(
126            Entry::new("first", metadata.clone()),
127            Entry::new("second", metadata)
128        );
129    }
130}