blob: 7c249268f02159c6baa787c36f4783f8b55a01cf [file] [log] [blame]
// 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)
}
}