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}