| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| use crate::*; |
| use std::collections::HashMap; |
| |
| /// Entry |
| /// |
| /// An entry representing a path and its associated metadata. |
| /// |
| /// Notes |
| /// ----- |
| /// If this entry is a directory, ``path`` **must** end with ``/``. |
| /// Otherwise, ``path`` **must not** end with ``/``. |
| #[gen_stub_pyclass] |
| #[pyclass(module = "opendal.types")] |
| pub struct Entry(ocore::Entry); |
| |
| impl Entry { |
| pub fn new(entry: ocore::Entry) -> Self { |
| Self(entry) |
| } |
| } |
| |
| #[gen_stub_pymethods] |
| #[pymethods] |
| impl Entry { |
| /// The path of entry relative to the operator's root. |
| #[getter] |
| pub fn path(&self) -> &str { |
| self.0.path() |
| } |
| |
| /// The name of entry, representing the last segment of the path. |
| #[getter] |
| pub fn name(&self) -> &str { |
| self.0.name() |
| } |
| |
| /// The metadata of this entry. |
| #[getter] |
| pub fn metadata(&self) -> Metadata { |
| Metadata::new(self.0.metadata().clone()) |
| } |
| |
| #[gen_stub(skip)] |
| fn __str__(&self) -> &str { |
| self.0.path() |
| } |
| |
| #[gen_stub(skip)] |
| fn __repr__(&self) -> String { |
| format!( |
| "Entry(path={:?}, metadata={})", |
| self.path(), |
| self.metadata().__repr__() |
| ) |
| } |
| } |
| |
| /// The metadata of an ``Entry``. |
| /// |
| /// The metadata is always tied to a specific context and is not a global |
| /// state. For example, two versions of the same path might have different |
| /// content lengths. |
| /// |
| /// Notes |
| /// ----- |
| /// In systems that support versioning, such as AWS S3, the metadata may |
| /// represent a specific version of a file. Use :attr:`version` to get |
| /// the version of a file if it is available. |
| #[gen_stub_pyclass] |
| #[pyclass(module = "opendal.types")] |
| pub struct Metadata(ocore::Metadata); |
| |
| impl Metadata { |
| pub fn new(meta: ocore::Metadata) -> Self { |
| Self(meta) |
| } |
| } |
| |
| #[gen_stub_pymethods] |
| #[pymethods] |
| impl Metadata { |
| /// The content disposition of this entry. |
| #[getter] |
| pub fn content_disposition(&self) -> Option<&str> { |
| self.0.content_disposition() |
| } |
| |
| /// The content length of this entry. |
| #[getter] |
| pub fn content_length(&self) -> u64 { |
| self.0.content_length() |
| } |
| |
| /// The content MD5 of this entry. |
| #[getter] |
| pub fn content_md5(&self) -> Option<&str> { |
| self.0.content_md5() |
| } |
| |
| /// The content type of this entry. |
| #[getter] |
| pub fn content_type(&self) -> Option<&str> { |
| self.0.content_type() |
| } |
| |
| /// The content encoding of this entry. |
| #[getter] |
| pub fn content_encoding(&self) -> Option<&str> { |
| self.0.content_encoding() |
| } |
| |
| /// The ETag of this entry. |
| #[getter] |
| pub fn etag(&self) -> Option<&str> { |
| self.0.etag() |
| } |
| |
| /// The mode of this entry. |
| #[getter] |
| pub fn mode(&self) -> EntryMode { |
| EntryMode::new(self.0.mode()) |
| } |
| |
| /// Whether this entry is a file. |
| #[getter] |
| pub fn is_file(&self) -> bool { |
| self.mode().is_file() |
| } |
| |
| /// Whether this entry is a directory. |
| #[getter] |
| pub fn is_dir(&self) -> bool { |
| self.mode().is_dir() |
| } |
| |
| /// The last modified timestamp of this entry. |
| #[gen_stub(override_return_type(type_repr = "datetime.datetime", imports=("datetime")))] |
| #[getter] |
| pub fn last_modified(&self) -> Option<jiff::Timestamp> { |
| self.0.last_modified().map(Into::into) |
| } |
| |
| /// The version of this entry. |
| #[getter] |
| pub fn version(&self) -> Option<&str> { |
| self.0.version() |
| } |
| |
| /// The user-defined metadata of this entry. |
| #[getter] |
| pub fn user_metadata(&self) -> Option<&HashMap<String, String>> { |
| self.0.user_metadata() |
| } |
| |
| #[gen_stub(skip)] |
| pub fn __repr__(&self) -> String { |
| let mut parts = vec![]; |
| |
| parts.push(format!("mode={}", self.0.mode())); |
| parts.push(format!( |
| "content_disposition={:?}", |
| self.0.content_disposition() |
| )); |
| parts.push(format!("content_length={}", self.0.content_length())); |
| parts.push(format!("content_md5={:?}", self.0.content_md5())); |
| parts.push(format!("content_type={:?}", self.0.content_type())); |
| parts.push(format!("content_encoding={:?}", self.0.content_encoding())); |
| parts.push(format!("etag={:?}", self.0.etag())); |
| parts.push(format!("last_modified={:?}", self.0.last_modified())); |
| parts.push(format!("version={:?}", self.0.version())); |
| parts.push(format!("user_metadata={:?}", self.0.user_metadata())); |
| |
| format!("Metadata({})", parts.join(", ")) |
| } |
| } |
| |
| /// EntryMode |
| /// |
| /// The mode of an entry, indicating if it is a file or a directory. |
| #[gen_stub_pyclass_enum] |
| #[pyclass(eq, eq_int, hash, frozen, module = "opendal.types")] |
| #[pyo3(rename_all = "PascalCase")] |
| #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
| pub enum EntryMode { |
| /// The entry is a file and has data to read. |
| FILE, |
| /// The entry is a directory and can be listed. |
| DIR, |
| /// The mode of the entry is unknown. |
| Unknown, |
| } |
| |
| impl EntryMode { |
| pub fn new(mode: ocore::EntryMode) -> Self { |
| match mode { |
| ocore::EntryMode::FILE => Self::FILE, |
| ocore::EntryMode::DIR => Self::DIR, |
| ocore::EntryMode::Unknown => Self::Unknown, |
| } |
| } |
| } |
| |
| #[gen_stub_pymethods] |
| #[pymethods] |
| impl EntryMode { |
| /// Check if the entry mode is `File`. |
| /// |
| /// Returns |
| /// ------- |
| /// bool |
| /// True if the entry is a file. |
| pub fn is_file(&self) -> bool { |
| matches!(self, EntryMode::FILE) |
| } |
| |
| /// Check if the entry mode is `Dir`. |
| /// |
| /// Returns |
| /// ------- |
| /// bool |
| /// True if the entry is a directory. |
| pub fn is_dir(&self) -> bool { |
| matches!(self, EntryMode::DIR) |
| } |
| } |