You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2023/04/11 15:26:59 UTC
[incubator-opendal] 01/01: refactor: Use chrono instead of time to work well with ecosystem
This is an automated email from the ASF dual-hosted git repository.
xuanwo pushed a commit to branch remove-time
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git
commit 100e3f274d04b3c4d8442f11559300c421ea3ce3
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Tue Apr 11 23:26:31 2023 +0800
refactor: Use chrono instead of time to work well with ecosystem
Signed-off-by: Xuanwo <gi...@xuanwo.io>
---
Cargo.lock | 3 +-
bindings/nodejs/Cargo.toml | 1 -
bindings/nodejs/src/lib.rs | 9 +++---
bindings/object_store/Cargo.toml | 1 -
bindings/object_store/src/lib.rs | 24 ++------------
core/Cargo.toml | 2 ++
core/src/raw/chrono_util.rs | 53 +++++++++++++++++++++++++++++++
core/src/raw/http_util/header.rs | 16 +++-------
core/src/raw/mod.rs | 3 ++
core/src/services/azblob/pager.rs | 15 ++-------
core/src/services/azdfs/pager.rs | 12 +------
core/src/services/fs/backend.rs | 6 ++--
core/src/services/ftp/backend.rs | 3 +-
core/src/services/ftp/pager.rs | 3 +-
core/src/services/gcs/backend.rs | 7 +---
core/src/services/gcs/pager.rs | 7 +---
core/src/services/hdfs/backend.rs | 5 ++-
core/src/services/hdfs/pager.rs | 4 +--
core/src/services/oss/pager.rs | 13 +-------
core/src/services/s3/pager.rs | 18 +----------
core/src/services/webdav/list_response.rs | 5 ++-
core/src/services/webhdfs/message.rs | 15 ++++-----
core/src/types/metadata.rs | 12 +++----
23 files changed, 101 insertions(+), 136 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 796ac0cb..87bcdc19 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2174,7 +2174,6 @@ version = "0.30.5"
dependencies = [
"async-trait",
"bytes",
- "chrono",
"futures",
"object_store",
"opendal",
@@ -2225,6 +2224,7 @@ dependencies = [
"bb8",
"bytes",
"cfg-if",
+ "chrono",
"criterion",
"dashmap",
"dotenvy",
@@ -2298,7 +2298,6 @@ dependencies = [
"napi-build",
"napi-derive",
"opendal",
- "time 0.3.17",
]
[[package]]
diff --git a/bindings/nodejs/Cargo.toml b/bindings/nodejs/Cargo.toml
index 8f1f287a..6931cbe0 100644
--- a/bindings/nodejs/Cargo.toml
+++ b/bindings/nodejs/Cargo.toml
@@ -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"
diff --git a/bindings/nodejs/src/lib.rs b/bindings/nodejs/src/lib.rs
index aa14cfaa..92c3f16b 100644
--- a/bindings/nodejs/src/lib.rs
+++ b/bindings/nodejs/src/lib.rs
@@ -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,
@@ -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())
}
}
diff --git a/bindings/object_store/Cargo.toml b/bindings/object_store/Cargo.toml
index 30618e03..e6c172f7 100644
--- a/bindings/object_store/Cargo.toml
+++ b/bindings/object_store/Cargo.toml
@@ -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" }
diff --git a/bindings/object_store/src/lib.rs b/bindings/object_store/src/lib.rs
index b9c6fb7c..f5d89f58 100644
--- a/bindings/object_store/src/lib.rs
+++ b/bindings/object_store/src/lib.rs
@@ -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;
@@ -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,
})
}
@@ -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,
}
}
diff --git a/core/Cargo.toml b/core/Cargo.toml
index 5320f093..c8d91187 100644
--- a/core/Cargo.toml
+++ b/core/Cargo.toml
@@ -133,6 +133,8 @@ suppaftp = { version = "4.5", default-features = false, features = [
"async-secure",
"async-rustls",
], optional = true }
+# Remove this crate after oss migrated
+chrono = "0.4.24"
time = { version = "0.3", features = ["serde"] }
tokio = { version = "1.27", features = ["fs"] }
tracing = { version = "0.1", optional = true }
diff --git a/core/src/raw/chrono_util.rs b/core/src/raw/chrono_util.rs
new file mode 100644
index 00000000..0f0415e8
--- /dev/null
+++ b/core/src/raw/chrono_util.rs
@@ -0,0 +1,53 @@
+// 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, UNIX_EPOCH};
+
+use chrono::{DateTime, 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, "intput timestamp overflow"))?;
+
+ Ok(st.into())
+}
diff --git a/core/src/raw/http_util/header.rs b/core/src/raw/http_util/header.rs
index 763d74b3..19075bf4 100644
--- a/core/src/raw/http_util/header.rs
+++ b/core/src/raw/http_util/header.rs
@@ -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;
@@ -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;
@@ -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) => {
@@ -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)?))
}
}
}
diff --git a/core/src/raw/mod.rs b/core/src/raw/mod.rs
index 18a925b5..4cfd69c7 100644
--- a/core/src/raw/mod.rs
+++ b/core/src/raw/mod.rs
@@ -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;
diff --git a/core/src/services/azblob/pager.rs b/core/src/services/azblob/pager.rs
index b0fad0e6..540b0164 100644
--- a/core/src/services/azblob/pager.rs
+++ b/core/src/services/azblob/pager.rs
@@ -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;
@@ -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);
diff --git a/core/src/services/azdfs/pager.rs b/core/src/services/azdfs/pager.rs
index 4f414a04..e3e29a02 100644
--- a/core/src/services/azdfs/pager.rs
+++ b/core/src/services/azdfs/pager.rs
@@ -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;
@@ -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 {
diff --git a/core/src/services/fs/backend.rs b/core/src/services/fs/backend.rs
index 1bed68a6..e5159db5 100644
--- a/core/src/services/fs/backend.rs
+++ b/core/src/services/fs/backend.rs
@@ -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;
@@ -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)?,
);
@@ -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)?,
);
diff --git a/core/src/services/ftp/backend.rs b/core/src/services/ftp/backend.rs
index cd724d7b..75262323 100644
--- a/core/src/services/ftp/backend.rs
+++ b/core/src/services/ftp/backend.rs
@@ -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;
@@ -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))
}
diff --git a/core/src/services/ftp/pager.rs b/core/src/services/ftp/pager.rs
index fc669efa..e1e1c0af 100644
--- a/core/src/services/ftp/pager.rs
+++ b/core/src/services/ftp/pager.rs
@@ -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::*;
@@ -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))
diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs
index bca412fa..0bbaddea 100644
--- a/core/src/services/gcs/backend.rs
+++ b/core/src/services/gcs/backend.rs
@@ -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;
@@ -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('/') {
diff --git a/core/src/services/gcs/pager.rs b/core/src/services/gcs/pager.rs
index 6cb66aac..bfa99981 100644
--- a/core/src/services/gcs/pager.rs
+++ b/core/src/services/gcs/pager.rs
@@ -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;
@@ -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);
diff --git a/core/src/services/hdfs/backend.rs b/core/src/services/hdfs/backend.rs
index e3869d4c..e13948d3 100644
--- a/core/src/services/hdfs/backend.rs
+++ b/core/src/services/hdfs/backend.rs
@@ -25,7 +25,6 @@ use std::sync::Arc;
use async_trait::async_trait;
use log::debug;
-use time::OffsetDateTime;
use super::error::parse_io_error;
use super::pager::HdfsPager;
@@ -362,7 +361,7 @@ impl Accessor for HdfsBackend {
};
let mut m = Metadata::new(mode);
m.set_content_length(meta.len());
- m.set_last_modified(OffsetDateTime::from(meta.modified()));
+ m.set_last_modified(meta.modified().into());
Ok(RpStat::new(m))
}
@@ -529,7 +528,7 @@ impl Accessor for HdfsBackend {
};
let mut m = Metadata::new(mode);
m.set_content_length(meta.len());
- m.set_last_modified(OffsetDateTime::from(meta.modified()));
+ m.set_last_modified(meta.modified().into());
Ok(RpStat::new(m))
}
diff --git a/core/src/services/hdfs/pager.rs b/core/src/services/hdfs/pager.rs
index ae68ba9d..28b8ca5f 100644
--- a/core/src/services/hdfs/pager.rs
+++ b/core/src/services/hdfs/pager.rs
@@ -56,7 +56,7 @@ impl oio::Page for HdfsPager {
let d = if de.is_file() {
let meta = Metadata::new(EntryMode::FILE)
.with_content_length(de.len())
- .with_last_modified(time::OffsetDateTime::from(de.modified()));
+ .with_last_modified(de.modified().into());
oio::Entry::new(&path, meta)
} else if de.is_dir() {
// Make sure we are returning the correct path.
@@ -87,7 +87,7 @@ impl oio::BlockingPage for HdfsPager {
let d = if de.is_file() {
let meta = Metadata::new(EntryMode::FILE)
.with_content_length(de.len())
- .with_last_modified(time::OffsetDateTime::from(de.modified()));
+ .with_last_modified(de.modified().into());
oio::Entry::new(&path, meta)
} else if de.is_dir() {
// Make sure we are returning the correct path.
diff --git a/core/src/services/oss/pager.rs b/core/src/services/oss/pager.rs
index 0ecae280..17a54ad8 100644
--- a/core/src/services/oss/pager.rs
+++ b/core/src/services/oss/pager.rs
@@ -22,8 +22,6 @@ use bytes::Buf;
use quick_xml::de;
use quick_xml::escape::unescape;
use serde::Deserialize;
-use time::format_description::well_known::Rfc3339;
-use time::OffsetDateTime;
use super::backend::OssBackend;
use super::error::parse_error;
@@ -114,16 +112,7 @@ impl oio::Page for OssPager {
meta.set_etag(&object.etag);
meta.set_content_length(object.size);
- let dt = OffsetDateTime::parse(object.last_modified.as_str(), &Rfc3339)
- .map(|v| {
- v.replace_nanosecond(0)
- .expect("replace nanosecond of last modified must succeed")
- })
- .map_err(|e| {
- Error::new(ErrorKind::Unexpected, "parse str into rfc 3339 datetime")
- .set_source(e)
- })?;
- meta.set_last_modified(dt);
+ meta.set_last_modified(parse_datetime_from_rfc3339(object.last_modified.as_str())?);
let rel = build_rel_path(&self.root, &object.key);
let path = unescape(&rel)
diff --git a/core/src/services/s3/pager.rs b/core/src/services/s3/pager.rs
index e7036134..250516df 100644
--- a/core/src/services/s3/pager.rs
+++ b/core/src/services/s3/pager.rs
@@ -21,15 +21,11 @@ use async_trait::async_trait;
use bytes::Buf;
use quick_xml::de;
use serde::Deserialize;
-use time::format_description::well_known::Rfc3339;
-use time::OffsetDateTime;
use super::core::S3Core;
use super::error::parse_error;
use crate::raw::*;
use crate::EntryMode;
-use crate::Error;
-use crate::ErrorKind;
use crate::Metadata;
use crate::Result;
@@ -120,19 +116,7 @@ impl oio::Page for S3Pager {
// object.last_modified provides more precious time that contains
// nanosecond, let's trim them.
- let dt = OffsetDateTime::parse(object.last_modified.as_str(), &Rfc3339)
- .map(|v| {
- v.replace_nanosecond(0)
- .expect("replace nanosecond of last modified must succeed")
- })
- .map_err(|e| {
- Error::new(
- ErrorKind::Unexpected,
- "parse last modified RFC3339 datetime",
- )
- .set_source(e)
- })?;
- meta.set_last_modified(dt);
+ meta.set_last_modified(parse_datetime_from_rfc3339(object.last_modified.as_str())?);
let de = oio::Entry::new(&build_rel_path(&self.core.root, &object.key), meta);
diff --git a/core/src/services/webdav/list_response.rs b/core/src/services/webdav/list_response.rs
index 12e34586..e8b5c700 100644
--- a/core/src/services/webdav/list_response.rs
+++ b/core/src/services/webdav/list_response.rs
@@ -16,9 +16,8 @@
// under the License.
use serde::Deserialize;
-use time::format_description::well_known::Rfc2822;
-use time::OffsetDateTime;
+use crate::raw::parse_datetime_from_rfc2822;
use crate::EntryMode;
use crate::Error;
use crate::ErrorKind;
@@ -83,7 +82,7 @@ impl ListOpResponse {
m.set_etag(v);
}
// https://www.rfc-editor.org/rfc/rfc4918#section-14.18
- m.set_last_modified(OffsetDateTime::parse(getlastmodified, &Rfc2822).unwrap());
+ m.set_last_modified(parse_datetime_from_rfc2822(getlastmodified)?);
Ok(m)
}
}
diff --git a/core/src/services/webhdfs/message.rs b/core/src/services/webhdfs/message.rs
index 76e0cc07..44228ae6 100644
--- a/core/src/services/webhdfs/message.rs
+++ b/core/src/services/webhdfs/message.rs
@@ -17,9 +17,9 @@
//! HTTP response messages
-use serde::Deserialize;
-
+use crate::raw::*;
use crate::*;
+use serde::Deserialize;
#[derive(Debug, Deserialize)]
pub(super) struct BooleanResp {
@@ -62,12 +62,11 @@ impl TryFrom<FileStatus> for Metadata {
FileStatusType::Directory => Metadata::new(EntryMode::DIR),
FileStatusType::File => Metadata::new(EntryMode::FILE),
};
- let till_now = time::Duration::milliseconds(value.modification_time);
- let last_modified = time::OffsetDateTime::UNIX_EPOCH
- .checked_add(till_now)
- .ok_or_else(|| Error::new(ErrorKind::Unexpected, "last modification overflowed!"))?;
- meta.set_last_modified(last_modified)
- .set_content_length(value.length);
+
+ meta.set_last_modified(parse_datetime_from_from_timestamp_millis(
+ value.modification_time,
+ )?)
+ .set_content_length(value.length);
Ok(meta)
}
}
diff --git a/core/src/types/metadata.rs b/core/src/types/metadata.rs
index cba43db6..a76f58fb 100644
--- a/core/src/types/metadata.rs
+++ b/core/src/types/metadata.rs
@@ -15,9 +15,9 @@
// specific language governing permissions and limitations
// under the License.
+use chrono::prelude::*;
use flagset::flags;
use flagset::FlagSet;
-use time::OffsetDateTime;
use crate::raw::*;
use crate::*;
@@ -42,7 +42,7 @@ pub struct Metadata {
content_range: Option<BytesContentRange>,
content_type: Option<String>,
etag: Option<String>,
- last_modified: Option<OffsetDateTime>,
+ last_modified: Option<DateTime<Utc>>,
}
impl Metadata {
@@ -246,8 +246,8 @@ impl Metadata {
/// `Last-Modified` is defined by [RFC 7232](https://httpwg.org/specs/rfc7232.html#header.last-modified)
/// Refer to [MDN Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) for more information.
///
- /// OpenDAL parse the raw value into [`OffsetDateTime`] for convenient.
- pub fn last_modified(&self) -> Option<OffsetDateTime> {
+ /// OpenDAL parse the raw value into [`DateTime`] for convenient.
+ pub fn last_modified(&self) -> Option<DateTime<Utc>> {
debug_assert!(
self.bit.contains(Metakey::LastModified) || self.bit.contains(Metakey::Complete),
"visiting not set metadata: last_modified, maybe a bug"
@@ -260,7 +260,7 @@ impl Metadata {
///
/// `Last-Modified` is defined by [RFC 7232](https://httpwg.org/specs/rfc7232.html#header.last-modified)
/// Refer to [MDN Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) for more information.
- pub fn set_last_modified(&mut self, last_modified: OffsetDateTime) -> &mut Self {
+ pub fn set_last_modified(&mut self, last_modified: DateTime<Utc>) -> &mut Self {
self.last_modified = Some(last_modified);
self.bit |= Metakey::LastModified;
self
@@ -270,7 +270,7 @@ impl Metadata {
///
/// `Last-Modified` is defined by [RFC 7232](https://httpwg.org/specs/rfc7232.html#header.last-modified)
/// Refer to [MDN Last-Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified) for more information.
- pub fn with_last_modified(mut self, last_modified: OffsetDateTime) -> Self {
+ pub fn with_last_modified(mut self, last_modified: DateTime<Utc>) -> Self {
self.last_modified = Some(last_modified);
self.bit |= Metakey::LastModified;
self