Skip to content

Commit

Permalink
refactor: Use chrono instead of time to work well with ecosystem (#1912)
Browse files Browse the repository at this point in the history
* refactor: Use chrono instead of time to work well with ecosystem

Signed-off-by: Xuanwo <github@xuanwo.io>

* Fix typo

Signed-off-by: Xuanwo <github@xuanwo.io>

* Remove time

Signed-off-by: Xuanwo <github@xuanwo.io>

* Fromat code

Signed-off-by: Xuanwo <github@xuanwo.io>

---------

Signed-off-by: Xuanwo <github@xuanwo.io>
  • Loading branch information
Xuanwo authored Apr 11, 2023
1 parent b8c29fd commit 42ad2dd
Show file tree
Hide file tree
Showing 24 changed files with 103 additions and 139 deletions.
4 changes: 1 addition & 3 deletions 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 bindings/nodejs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ napi = { version = "2.11.3", default-features = false, features = [
] }
napi-derive = "2.12.2"
opendal = { version = "0.30", path = "../../core" }
time = { version = "0.3.17", features = ["formatting"] }

[build-dependencies]
napi-build = "2"
9 changes: 4 additions & 5 deletions bindings/nodejs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use std::time::Duration;

use futures::TryStreamExt;
use napi::bindgen_prelude::*;
use time::format_description::well_known::Rfc3339;

fn build_operator(
scheme: opendal::Scheme,
Expand Down Expand Up @@ -599,12 +598,12 @@ impl Metadata {
self.0.etag().map(|s| s.to_string())
}

/// Last Modified of this object.(UTC)
/// Last Modified of this object.
///
/// We will output this time in RFC3339 format like `1996-12-19T16:39:57+08:00`.
#[napi(getter)]
pub fn last_modified(&self) -> Option<String> {
self.0
.last_modified()
.map(|ta| ta.format(&Rfc3339).unwrap())
self.0.last_modified().map(|ta| ta.to_rfc3339())
}
}

Expand Down
1 change: 0 additions & 1 deletion bindings/object_store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ version.workspace = true
[dependencies]
async-trait = "0.1"
bytes = "1"
chrono = "0.4.23"
futures = "0.3"
object_store = "0.5"
opendal = { version = "0.30", path = "../../core" }
Expand Down
24 changes: 2 additions & 22 deletions bindings/object_store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ use std::task::Poll;

use async_trait::async_trait;
use bytes::Bytes;
use chrono::DateTime;
use chrono::NaiveDateTime;
use chrono::Utc;
use futures::stream::BoxStream;
use futures::Stream;
use futures::StreamExt;
Expand Down Expand Up @@ -117,18 +114,9 @@ impl ObjectStore for OpendalStore {
.await
.map_err(|err| format_object_store_error(err, location.as_ref()))?;

let (secs, nsecs) = meta
.last_modified()
.map(|v| (v.unix_timestamp(), v.nanosecond()))
.unwrap_or((0, 0));

Ok(ObjectMeta {
location: location.clone(),
last_modified: DateTime::from_utc(
NaiveDateTime::from_timestamp_opt(secs, nsecs)
.expect("returning timestamp must be valid"),
Utc,
),
last_modified: meta.last_modified().unwrap_or_default(),
size: meta.content_length() as usize,
})
}
Expand Down Expand Up @@ -251,17 +239,9 @@ fn format_object_store_error(err: opendal::Error, path: &str) -> object_store::E
}

fn format_object_meta(path: &str, meta: &Metadata) -> ObjectMeta {
let (secs, nsecs) = meta
.last_modified()
.map(|v| (v.unix_timestamp(), v.nanosecond()))
.unwrap_or((0, 0));
ObjectMeta {
location: path.into(),
last_modified: DateTime::from_utc(
NaiveDateTime::from_timestamp_opt(secs, nsecs)
.expect("returning timestamp must be valid"),
Utc,
),
last_modified: meta.last_modified().unwrap_or_default(),
size: meta.content_length() as usize,
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ suppaftp = { version = "4.5", default-features = false, features = [
"async-secure",
"async-rustls",
], optional = true }
time = { version = "0.3", features = ["serde"] }
chrono = "0.4.24"
tokio = { version = "1.27", features = ["fs"] }
tracing = { version = "0.1", optional = true }
trust-dns-resolver = { version = "0.22", optional = true }
Expand Down
55 changes: 55 additions & 0 deletions core/src/raw/chrono_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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 std::time::Duration;
use std::time::UNIX_EPOCH;

use chrono::DateTime;
use chrono::Utc;

use crate::*;

/// Parse dateimt from rfc2822.
///
/// For example: `Fri, 28 Nov 2014 21:00:09 +0900`
pub fn parse_datetime_from_rfc2822(s: &str) -> Result<DateTime<Utc>> {
DateTime::parse_from_rfc2822(s)
.map(|v| v.into())
.map_err(|e| {
Error::new(ErrorKind::Unexpected, "parse datetime from rfc2822 failed").set_source(e)
})
}

/// Parse dateimt from rfc3339.
///
/// For example: `2014-11-28T21:00:09+09:00`
pub fn parse_datetime_from_rfc3339(s: &str) -> Result<DateTime<Utc>> {
DateTime::parse_from_rfc3339(s)
.map(|v| v.into())
.map_err(|e| {
Error::new(ErrorKind::Unexpected, "parse datetime from rfc3339 failed").set_source(e)
})
}

/// parse datetime from given timestamp_millis
pub fn parse_datetime_from_from_timestamp_millis(s: i64) -> Result<DateTime<Utc>> {
let st = UNIX_EPOCH
.checked_add(Duration::from_millis(s as u64))
.ok_or_else(|| Error::new(ErrorKind::Unexpected, "input timestamp overflow"))?;

Ok(st.into())
}
16 changes: 4 additions & 12 deletions core/src/raw/http_util/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

use base64::engine::general_purpose;
use base64::Engine;
use chrono::DateTime;
use chrono::Utc;
use http::header::HeaderName;
use http::header::CONTENT_DISPOSITION;
use http::header::CONTENT_LENGTH;
Expand All @@ -28,8 +30,6 @@ use http::header::LOCATION;
use http::HeaderMap;
use http::HeaderValue;
use md5::Digest;
use time::format_description::well_known::Rfc2822;
use time::OffsetDateTime;

use crate::raw::*;
use crate::EntryMode;
Expand Down Expand Up @@ -130,7 +130,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<OffsetDateTime>> {
pub fn parse_last_modified(headers: &HeaderMap) -> Result<Option<DateTime<Utc>>> {
match headers.get(LAST_MODIFIED) {
None => Ok(None),
Some(v) => {
Expand All @@ -142,16 +142,8 @@ pub fn parse_last_modified(headers: &HeaderMap) -> Result<Option<OffsetDateTime>
.with_operation("http_util::parse_last_modified")
.set_source(e)
})?;
let t = OffsetDateTime::parse(v, &Rfc2822).map_err(|e| {
Error::new(
ErrorKind::Unexpected,
"header value is not valid rfc2822 time",
)
.with_operation("http_util::parse_last_modified")
.set_source(e)
})?;

Ok(Some(t))
Ok(Some(parse_datetime_from_rfc2822(v)?))
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions core/src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,8 @@ pub use http_util::*;
mod serde_util;
pub use serde_util::*;

mod chrono_util;
pub use chrono_util::*;

// Expose as a pub mod to avoid confusing.
pub mod adapters;
15 changes: 3 additions & 12 deletions core/src/services/azblob/pager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ use async_trait::async_trait;
use bytes::Buf;
use quick_xml::de;
use serde::Deserialize;
use time::format_description::well_known::Rfc2822;
use time::OffsetDateTime;

use super::core::AzblobCore;
use super::error::parse_error;
Expand Down Expand Up @@ -115,16 +113,9 @@ impl oio::Page for AzblobPager {
.with_content_length(object.properties.content_length)
.with_content_md5(object.properties.content_md5)
.with_content_type(object.properties.content_type)
.with_last_modified(
OffsetDateTime::parse(object.properties.last_modified.as_str(), &Rfc2822)
.map_err(|e| {
Error::new(
ErrorKind::Unexpected,
"parse last modified RFC2822 datetime",
)
.set_source(e)
})?,
);
.with_last_modified(parse_datetime_from_rfc2822(
object.properties.last_modified.as_str(),
)?);

let de = oio::Entry::new(&build_rel_path(&self.core.root, &object.name), meta);

Expand Down
12 changes: 1 addition & 11 deletions core/src/services/azdfs/pager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ use std::sync::Arc;
use async_trait::async_trait;
use serde::Deserialize;
use serde_json::de;
use time::format_description::well_known::Rfc2822;
use time::OffsetDateTime;

use super::core::AzdfsCore;
use super::error::parse_error;
Expand Down Expand Up @@ -107,15 +105,7 @@ impl oio::Page for AzdfsPager {
Error::new(ErrorKind::Unexpected, "content length is not valid integer")
.set_source(err)
})?)
.with_last_modified(
OffsetDateTime::parse(&object.last_modified, &Rfc2822).map_err(|e| {
Error::new(
ErrorKind::Unexpected,
"last modified is not valid RFC2822 datetime",
)
.set_source(e)
})?,
);
.with_last_modified(parse_datetime_from_rfc2822(&object.last_modified)?);

let mut path = build_rel_path(&self.core.root, &object.name);
if mode == EntryMode::DIR {
Expand Down
6 changes: 3 additions & 3 deletions core/src/services/fs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use std::path::PathBuf;

use async_compat::Compat;
use async_trait::async_trait;
use chrono::DateTime;
use log::debug;
use time::OffsetDateTime;
use tokio::fs;
use uuid::Uuid;

Expand Down Expand Up @@ -494,7 +494,7 @@ impl Accessor for FsBackend {
.with_content_length(meta.len())
.with_last_modified(
meta.modified()
.map(OffsetDateTime::from)
.map(DateTime::from)
.map_err(parse_io_error)?,
);

Expand Down Expand Up @@ -706,7 +706,7 @@ impl Accessor for FsBackend {
.with_content_length(meta.len())
.with_last_modified(
meta.modified()
.map(OffsetDateTime::from)
.map(DateTime::from)
.map_err(parse_io_error)?,
);

Expand Down
3 changes: 1 addition & 2 deletions core/src/services/ftp/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ use suppaftp::types::Response;
use suppaftp::FtpError;
use suppaftp::FtpStream;
use suppaftp::Status;
use time::OffsetDateTime;
use tokio::sync::OnceCell;

use super::pager::FtpPager;
Expand Down Expand Up @@ -419,7 +418,7 @@ impl Accessor for FtpBackend {
};
let mut meta = Metadata::new(mode);
meta.set_content_length(file.size() as u64);
meta.set_last_modified(OffsetDateTime::from(file.modified()));
meta.set_last_modified(file.modified().into());

Ok(RpStat::new(meta))
}
Expand Down
3 changes: 1 addition & 2 deletions core/src/services/ftp/pager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ use std::vec::IntoIter;

use async_trait::async_trait;
use suppaftp::list::File;
use time::OffsetDateTime;

use crate::raw::*;
use crate::*;
Expand Down Expand Up @@ -62,7 +61,7 @@ impl oio::Page for FtpPager {
&path,
Metadata::new(EntryMode::FILE)
.with_content_length(de.size() as u64)
.with_last_modified(OffsetDateTime::from(de.modified())),
.with_last_modified(de.modified().into()),
)
} else if de.is_directory() {
oio::Entry::new(&format!("{}/", &path), Metadata::new(EntryMode::DIR))
Expand Down
7 changes: 1 addition & 6 deletions core/src/services/gcs/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ use reqsign_0_9::GoogleTokenLoad;
use reqsign_0_9::GoogleTokenLoader;
use serde::Deserialize;
use serde_json;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;

use super::core::GcsCore;
use super::error::parse_error;
Expand Down Expand Up @@ -422,10 +420,7 @@ impl Accessor for GcsBackend {
m.set_content_type(&meta.content_type);
}

let datetime = OffsetDateTime::parse(&meta.updated, &Rfc3339).map_err(|e| {
Error::new(ErrorKind::Unexpected, "parse date time with rfc 3339").set_source(e)
})?;
m.set_last_modified(datetime);
m.set_last_modified(parse_datetime_from_rfc3339(&meta.updated)?);

Ok(RpStat::new(m))
} else if resp.status() == StatusCode::NOT_FOUND && path.ends_with('/') {
Expand Down
7 changes: 1 addition & 6 deletions core/src/services/gcs/pager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ use std::sync::Arc;
use async_trait::async_trait;
use serde::Deserialize;
use serde_json;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;

use super::core::GcsCore;
use super::error::parse_error;
Expand Down Expand Up @@ -113,10 +111,7 @@ impl oio::Page for GcsPager {
meta.set_content_type(&object.content_type);
}

let dt = OffsetDateTime::parse(object.updated.as_str(), &Rfc3339).map_err(|e| {
Error::new(ErrorKind::Unexpected, "parse last modified as rfc3339").set_source(e)
})?;
meta.set_last_modified(dt);
meta.set_last_modified(parse_datetime_from_rfc3339(object.updated.as_str())?);

let de = oio::Entry::new(&build_rel_path(&self.core.root, &object.name), meta);

Expand Down
Loading

0 comments on commit 42ad2dd

Please sign in to comment.