Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f672ba0
refactor(raw): add Timestamp wrapper around jiff::Timestamp
dami0806 Oct 12, 2025
d3e90f0
refactor(raw): remove jiff_util module and expose time module
dami0806 Oct 12, 2025
9e045d4
refactor(raw): migrate raw utilities to use Timestamp wrapper
dami0806 Oct 12, 2025
44267e2
refactor(types): migrate types layer to use Timestamp wrapper
dami0806 Oct 12, 2025
3b5a2f9
refactor(services): migrate cloud
dami0806 Oct 12, 2025
c524280
refactor(services): migrate
dami0806 Oct 12, 2025
8ebbb36
refactor(services): migrate other
dami0806 Oct 12, 2025
9640799
chore: update bin/ofs Cargo.lock
dami0806 Oct 12, 2025
90b564a
fix(bindings/java): migrate to use
dami0806 Oct 12, 2025
b113811
fix(bindings/python): migrate to
dami0806 Oct 12, 2025
cde0223
fix(bindings/nodejs): replace
dami0806 Oct 12, 2025
1e080d6
fix(bindings/c): use into_inner()
dami0806 Oct 12, 2025
0de9fea
fix(integrations/object_store):
dami0806 Oct 12, 2025
d24fde0
fix(bindings): resolve additional
dami0806 Oct 12, 2025
fa3f279
refactor: add as_millisecond to Timestamp and fix bindings
dami0806 Oct 12, 2025
4dd5256
feat(bindings/python): add Timestamp wrapper for datetime conversion
dami0806 Oct 12, 2025
bd88579
fix(integrations/fuse3): use into_inner for Timestamp to SystemTime c…
dami0806 Oct 12, 2025
d0b9743
chore(fmt): apply rustfmt for object_store
dami0806 Oct 12, 2025
2c4520c
fix(integrations/unftp-sbe): use into_inner for Timestamp to SystemTi…
dami0806 Oct 12, 2025
dee68b8
Merge branch 'main' into refactor/jiff-timestamp-wrapper
tisonkun Oct 14, 2025
edb0f55
fine tune boundary
tisonkun Oct 14, 2025
1ef75d1
fixup ci
tisonkun Oct 14, 2025
cceacc4
fmt
tisonkun Oct 14, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion bin/oay/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion bin/oay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ axum = { version = "0.8.6" }
dav-server = { version = "0.8", optional = true }
dav-server-opendalfs = { version = "0.6.0", path = "../../integrations/dav-server", optional = true }
futures-util = { version = "0.3.29", optional = true }
jiff = { version = "0.2.15" }
log = { version = "0.4.27" }
logforth = { version = "0.28.1", features = ["starter-log"] }
opendal = { version = "0.54.0", path = "../../core", features = [
Expand Down
4 changes: 2 additions & 2 deletions bin/ofs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bindings/c/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl opendal_metadata {
let mtime = self.deref().last_modified();
match mtime {
None => -1,
Some(time) => time.as_millisecond(),
Some(time) => time.into_inner().as_millisecond(),
}
}
}
1 change: 0 additions & 1 deletion bindings/cpp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ anyhow = { version = "1.0.100" }
cxx = { version = "1.0.186" }
cxx-async = { version = "0.1.3", optional = true }
futures = { version = "0.3.31" }
jiff = { version = "0.2.15" }
# this crate won't be published, we always use the local version
opendal = { version = ">=0", path = "../../core", features = ["blocking"] }
tokio = { version = "1.27", features = ["fs", "macros", "rt-multi-thread"] }
Expand Down
1 change: 0 additions & 1 deletion bindings/haskell/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ crate-type = ["cdylib"]
doc = false

[dependencies]
jiff = { version = "0.2.15" }
log = { version = "0.4", features = ["std"] }
# this crate won't be published, we always use the local version
opendal = { version = ">=0", path = "../../core", features = [
Expand Down
1 change: 0 additions & 1 deletion bindings/java/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ services-compfs = ["opendal/services-compfs"]

[dependencies]
anyhow = { version = "1.0.100" }
jiff = { version = "0.2.15" }
jni = { version = "0.21.1" }
# this crate won't be published, we always use the local version
opendal = { version = ">=0", path = "../../core", features = [
Expand Down
22 changes: 12 additions & 10 deletions bindings/java/src/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// under the License.

use crate::Result;
use jiff::Timestamp;
use jni::JNIEnv;
use jni::objects::JObject;
use jni::objects::JString;
Expand Down Expand Up @@ -127,7 +126,7 @@ pub(crate) fn read_instant_field_to_timestamp(
env: &mut JNIEnv<'_>,
obj: &JObject,
field: &str,
) -> Result<Option<Timestamp>> {
) -> Result<Option<opendal::raw::Timestamp>> {
let result = env.get_field(obj, field, "Ljava/time/Instant;")?.l()?;
if result.is_null() {
return Ok(None);
Expand All @@ -137,14 +136,17 @@ pub(crate) fn read_instant_field_to_timestamp(
.call_method(&result, "getEpochSecond", "()J", &[])?
.j()?;
let nano = env.call_method(&result, "getNano", "()I", &[])?.i()?;
Timestamp::new(epoch_second, nano).map(Some).map_err(|err| {
Error::new(
ErrorKind::Unexpected,
format!("invalid timestamp: seconds={epoch_second}, nanos={nano}"),
)
.set_source(err)
.into()
})

opendal::raw::Timestamp::from_second(epoch_second)
.map(Some)
.map_err(|err| {
Error::new(
ErrorKind::Unexpected,
format!("invalid timestamp: seconds={epoch_second}, nanos={nano}"),
)
.set_source(err)
.into()
})
}
Comment on lines 138 to 150
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is a bug I'll fix then.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up at #6663


pub(crate) fn offset_length_to_range(offset: i64, length: i64) -> Result<(Bound<u64>, Bound<u64>)> {
Expand Down
4 changes: 2 additions & 2 deletions bindings/java/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ fn make_metadata<'a>(env: &mut JNIEnv<'a>, metadata: Metadata) -> Result<JObject
"ofEpochSecond",
"(JJ)Ljava/time/Instant;",
&[
JValue::Long(v.as_second()),
JValue::Long(v.subsec_nanosecond() as jlong),
JValue::Long(v.into_inner().as_second()),
JValue::Long(v.into_inner().subsec_nanosecond() as jlong),
],
)?
.l()?)
Expand Down
14 changes: 7 additions & 7 deletions bindings/nodejs/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
// under the License.

use napi::bindgen_prelude::BigInt;
use opendal::raw::{BytesRange, parse_datetime_from_rfc3339};
use opendal::raw::{BytesRange, Timestamp};
use std::collections::HashMap;

#[napi(object)]
Expand Down Expand Up @@ -79,10 +79,10 @@ impl From<StatOptions> for opendal::options::StatOptions {
fn from(value: StatOptions) -> Self {
let if_modified_since = value
.if_modified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());
let if_unmodified_since = value
.if_unmodified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());

Self {
if_modified_since,
Expand Down Expand Up @@ -215,10 +215,10 @@ impl From<ReadOptions> for opendal::options::ReadOptions {
let range = value.make_range();
let if_modified_since = value
.if_modified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());
let if_unmodified_since = value
.if_unmodified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());

Self {
version: value.version,
Expand Down Expand Up @@ -329,10 +329,10 @@ impl From<ReaderOptions> for opendal::options::ReaderOptions {
fn from(value: ReaderOptions) -> Self {
let if_modified_since = value
.if_modified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());
let if_unmodified_since = value
.if_unmodified_since
.and_then(|v| parse_datetime_from_rfc3339(&v).ok());
.and_then(|v| v.parse::<Timestamp>().ok());

Self {
version: value.version,
Expand Down
5 changes: 4 additions & 1 deletion bindings/ocaml/src/operator/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,8 @@ pub fn metadata_etag(metadata: &mut Metadata) -> Option<String> {
#[ocaml::func]
#[ocaml::sig("metadata -> int64 option ")]
pub fn metadata_last_modified(metadata: &mut Metadata) -> Option<i64> {
metadata.0.last_modified().map(|t| t.as_second())
metadata
.0
.last_modified()
.map(|t| t.into_inner().as_second())
}
5 changes: 2 additions & 3 deletions bindings/python/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// under the License.

use crate::*;
use jiff::Timestamp;
use std::collections::HashMap;

#[pyclass(module = "opendal")]
Expand Down Expand Up @@ -121,8 +120,8 @@ impl Metadata {

/// Last modified time
#[getter]
pub fn last_modified(&self) -> Option<Timestamp> {
self.0.last_modified()
pub fn last_modified(&self) -> Option<jiff::Timestamp> {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, jiff::Timestamp has native pyo3 support?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

PyO3/pyo3#4823 and others.

self.0.last_modified().map(Into::into)
}

/// Version of this entry, if available.
Expand Down
21 changes: 10 additions & 11 deletions bindings/python/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
// under the License.

use dict_derive::FromPyObject;
use jiff::Timestamp;
use opendal::{self as ocore, raw::BytesRange};
use pyo3::pyclass;
use std::collections::HashMap;
Expand All @@ -33,8 +32,8 @@ pub struct ReadOptions {
pub size: Option<usize>,
pub if_match: Option<String>,
pub if_none_match: Option<String>,
pub if_modified_since: Option<Timestamp>,
pub if_unmodified_since: Option<Timestamp>,
pub if_modified_since: Option<jiff::Timestamp>,
pub if_unmodified_since: Option<jiff::Timestamp>,
pub content_type: Option<String>,
pub cache_control: Option<String>,
pub content_disposition: Option<String>,
Expand Down Expand Up @@ -72,8 +71,8 @@ impl From<ReadOptions> for ocore::options::ReadOptions {
version: opts.version,
if_match: opts.if_match,
if_none_match: opts.if_none_match,
if_modified_since: opts.if_modified_since,
if_unmodified_since: opts.if_unmodified_since,
if_modified_since: opts.if_modified_since.map(Into::into),
if_unmodified_since: opts.if_unmodified_since.map(Into::into),
concurrent: opts.concurrent.unwrap_or_default(),
chunk: opts.chunk,
gap: opts.gap,
Expand All @@ -90,8 +89,8 @@ impl From<ReadOptions> for ocore::options::ReaderOptions {
version: opts.version,
if_match: opts.if_match,
if_none_match: opts.if_none_match,
if_modified_since: opts.if_modified_since,
if_unmodified_since: opts.if_unmodified_since,
if_modified_since: opts.if_modified_since.map(Into::into),
if_unmodified_since: opts.if_unmodified_since.map(Into::into),
concurrent: opts.concurrent.unwrap_or_default(),
chunk: opts.chunk,
gap: opts.gap,
Expand Down Expand Up @@ -146,8 +145,8 @@ pub struct StatOptions {
pub version: Option<String>,
pub if_match: Option<String>,
pub if_none_match: Option<String>,
pub if_modified_since: Option<Timestamp>,
pub if_unmodified_since: Option<Timestamp>,
pub if_modified_since: Option<jiff::Timestamp>,
pub if_unmodified_since: Option<jiff::Timestamp>,
pub content_type: Option<String>,
pub cache_control: Option<String>,
pub content_disposition: Option<String>,
Expand All @@ -159,8 +158,8 @@ impl From<StatOptions> for ocore::options::StatOptions {
version: opts.version,
if_match: opts.if_match,
if_none_match: opts.if_none_match,
if_modified_since: opts.if_modified_since,
if_unmodified_since: opts.if_unmodified_since,
if_modified_since: opts.if_modified_since.map(Into::into),
if_unmodified_since: opts.if_unmodified_since.map(Into::into),
override_content_type: opts.content_type,
override_cache_control: opts.cache_control,
override_content_disposition: opts.content_disposition,
Expand Down
1 change: 0 additions & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
html_logo_url = "https://raw.githubusercontent.com/apache/opendal/main/website/static/img/logo.svg"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(docsrs, doc(auto_cfg))]
//! Apache OpenDAL™ is an Open Data Access Layer that enables seamless interaction with diverse storage services.
//!
//! OpenDAL's development is guided by its vision of **One Layer, All Storage** and its core principles: **Open Community**, **Solid Foundation**, **Fast Access**, **Object Storage First**, and **Extensible Architecture**. Read the explained vision at [OpenDAL Vision](https://opendal.apache.org/vision).
Expand Down
3 changes: 1 addition & 2 deletions core/src/raw/adapters/typed_kv/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ use crate::ErrorKind;
use crate::Metadata;
use crate::Result;
use crate::Scheme;
use crate::raw::MaybeSend;
use jiff::Timestamp;
use crate::raw::{MaybeSend, Timestamp};
use std::fmt::Debug;
use std::future::Future;
use std::future::ready;
Expand Down
3 changes: 1 addition & 2 deletions core/src/raw/http_util/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ use http::header::CONTENT_TYPE;
use http::header::ETAG;
use http::header::LAST_MODIFIED;
use http::header::LOCATION;
use jiff::Timestamp;
use md5::Digest;

use crate::EntryMode;
Expand Down Expand Up @@ -95,7 +94,7 @@ pub fn parse_content_range(headers: &HeaderMap) -> Result<Option<BytesContentRan
/// Parse last modified from header map.
pub fn parse_last_modified(headers: &HeaderMap) -> Result<Option<Timestamp>> {
parse_header_to_str(headers, LAST_MODIFIED)?
.map(parse_datetime_from_rfc2822)
.map(Timestamp::parse_rfc2822)
.transpose()
}

Expand Down
Loading
Loading