From edfadfd3aa198ed9e67a34e1b287e3313d1754fe Mon Sep 17 00:00:00 2001 From: Niel Drummond Date: Wed, 12 Jan 2022 16:32:34 +0000 Subject: [PATCH] Migrate from chrono to time 0.3 --- Cargo.toml | 4 +- .../src/main/java/bollard/BollardCodegen.java | 6 +- .../src/main/resources/bollard/Cargo.mustache | 2 +- .../main/resources/bollard/models.mustache | 31 +++++- codegen/target/generated-sources/Cargo.toml | 2 +- codegen/target/generated-sources/README.md | 2 +- .../target/generated-sources/src/models.rs | 102 +++++++++++++----- examples/hoover.rs | 6 +- src/container.rs | 14 ++- src/docker.rs | 29 ++++- src/system.rs | 19 ++-- tests/system_test.rs | 4 +- 12 files changed, 160 insertions(+), 61 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index beac7f50..2df9a33d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,8 @@ ct_logs = ["ssl", "ct-logs"] [dependencies] base64 = "0.13" -bollard-stubs = { version = "1.41.0" } +bollard-stubs = { version = "1.41.0", path = "codegen/target/generated-sources" } bytes = "1" -chrono = { version = "0.4", features = ["serde"] } ct-logs = { version = "0.9.0", optional = true } dirs-next = "2.0" futures-core = "0.3" @@ -46,6 +45,7 @@ serde_json = "1.0" serde_urlencoded = "0.7" tokio = { version = "1.7", features = ["time", "fs", "net", "rt", "rt-multi-thread", "io-util"] } thiserror = "1.0" +time = { version = "0.3", features = ["formatting", "parsing"] } tokio-util = { version = "0.6", features = ["codec"] } url = "2.2" webpki-roots = { version = "0.22", optional = true } diff --git a/codegen/src/main/java/bollard/BollardCodegen.java b/codegen/src/main/java/bollard/BollardCodegen.java index 96d43daa..9268c53c 100644 --- a/codegen/src/main/java/bollard/BollardCodegen.java +++ b/codegen/src/main/java/bollard/BollardCodegen.java @@ -22,6 +22,7 @@ public class BollardCodegen extends RustServerCodegen { public BollardCodegen() { super(); + typeMapping.put("DateTime", "OffsetDateTime"); } // Declare custom additions to inline enums that are behaving differently @@ -136,9 +137,10 @@ public Map postProcessAllModels(Map objs) { } else if (prop.name.equals("_type")) { prop.name = "typ"; } - if (prop.dataFormat != null && prop.dataFormat.equals("dateTime")) { + if (prop.dataFormat != null && (prop.dataFormat.equals("dateTime") || prop.datatype.equals("OffsetDateTime"))) { // set DateTime format on properties where appropriate - prop.datatype = "DateTime"; + prop.vendorExtensions.put("x-rustgen-is-datetime", true); + prop.datatype = "OffsetDateTime"; } if (prop.isEnum) { if (enumToString.contains(model.classname)) { diff --git a/codegen/src/main/resources/bollard/Cargo.mustache b/codegen/src/main/resources/bollard/Cargo.mustache index d71d9a1c..3a242c4d 100644 --- a/codegen/src/main/resources/bollard/Cargo.mustache +++ b/codegen/src/main/resources/bollard/Cargo.mustache @@ -7,7 +7,7 @@ license = "Apache-2.0" edition = "2018" [dependencies] -chrono = { version = "0.4", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } +time = { version = "0.3", features = ["formatting", "parsing"] } serde_with = "1.4" diff --git a/codegen/src/main/resources/bollard/models.mustache b/codegen/src/main/resources/bollard/models.mustache index 6a932c77..50bd5a82 100644 --- a/codegen/src/main/resources/bollard/models.mustache +++ b/codegen/src/main/resources/bollard/models.mustache @@ -9,8 +9,7 @@ use std::collections::HashMap; use std::default::Default; use std::hash::Hash; -use chrono::DateTime; -use chrono::Utc; +use time::OffsetDateTime; fn deserialize_nonoptional_vec<'de, D: Deserializer<'de>, T: DeserializeOwned>( d: D, @@ -24,6 +23,28 @@ fn deserialize_nonoptional_map<'de, D: Deserializer<'de>, T: DeserializeOwned>( serde::Deserialize::deserialize(d).map(|x: Option<_>| x.unwrap_or(HashMap::new())) } +fn deserialize_timestamp<'de, D: Deserializer<'de>>( + d: D +) -> Result, D::Error> { + let opt: Option = serde::Deserialize::deserialize(d)?; + if let Some(s) = opt { + Ok(Some( + OffsetDateTime::parse(&s, &time::format_description::well_known::Rfc3339) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?, + )) + } else { + Ok(None) + } +} + +fn serialize_timestamp(date: &Option, s: S) -> Result { + match date { + Some(inner) => Ok(s.serialize_str(&inner.format(&time::format_description::well_known::Rfc3339) + .map_err(|e| serde::ser::Error::custom(format!("{:?}", e)))?)?), + None => Ok(s.serialize_str("")?) + } +} + {{#models}}{{#model}} {{#description}}/// {{{description}}} {{/description}}{{#isEnum}}/// Enumeration of values. @@ -68,10 +89,12 @@ pub struct {{classname}} { #[serde(deserialize_with = "deserialize_nonoptional_map")]{{/isListContainer}}{{#isListContainer}} #[serde(deserialize_with = "deserialize_nonoptional_vec")]{{/isListContainer}}{{/isContainer}}{{#isEnum}} #[serde(skip_serializing_if="Option::is_none")] - #[serde(with = "serde_with::rust::string_empty_as_none")]{{/isEnum}} + #[serde(with = "serde_with::rust::string_empty_as_none")]{{/isEnum}}{{#vendorExtensions.x-rustgen-is-datetime}} + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]{{/vendorExtensions.x-rustgen-is-datetime}} pub {{name}}: {{#isEnum}}Option<{{classname}}{{enumName}}>{{/isEnum}}{{^isEnum}}{{#isListContainer}}Vec<{{#items}}{{{datatype}}}{{/items}}>{{/isListContainer}}{{^isListContainer}}{{#isContainer}}HashMap{{/isContainer}}{{^isContainer}}{{{datatype}}}{{/isContainer}}{{/isListContainer}}{{/isEnum}}{{#vendorExtensions}}{{/vendorExtensions}}, {{/required}}{{^required}} - #[serde(skip_serializing_if="Option::is_none")] + #[serde(skip_serializing_if="Option::is_none")]{{#vendorExtensions.x-rustgen-is-datetime}} + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]{{/vendorExtensions.x-rustgen-is-datetime}} pub {{name}}: Option<{{#isEnum}}{{classname}}{{enumName}}{{/isEnum}}{{^isEnum}}{{#isListContainer}}Vec<{{#items}}{{{datatype}}}{{/items}}>{{/isListContainer}}{{^isListContainer}}{{#isContainer}}HashMap{{/isContainer}}{{^isContainer}}{{{datatype}}}{{/isContainer}}{{/isListContainer}}{{/isEnum}}{{#vendorExtensions}}{{/vendorExtensions}}>, {{/required}} diff --git a/codegen/target/generated-sources/Cargo.toml b/codegen/target/generated-sources/Cargo.toml index 466f2c47..d278ad8b 100644 --- a/codegen/target/generated-sources/Cargo.toml +++ b/codegen/target/generated-sources/Cargo.toml @@ -7,7 +7,7 @@ license = "Apache-2.0" edition = "2018" [dependencies] -chrono = { version = "0.4", features = ["serde"] } serde = { version = "1.0", features = ["derive"] } +time = { version = "0.3", features = ["formatting", "parsing"] } serde_with = "1.4" diff --git a/codegen/target/generated-sources/README.md b/codegen/target/generated-sources/README.md index 007520c5..3c57fb48 100644 --- a/codegen/target/generated-sources/README.md +++ b/codegen/target/generated-sources/README.md @@ -9,7 +9,7 @@ To see how to make this your own, look here: - API version: 1.41.0 - Code generation suffix: 0 -- Build date: 2021-02-27T07:18:46.822Z +- Build date: 2022-01-18T17:41:15.437Z This autogenerated project defines an API crate `bollard-stubs` which contains: * Data types representing the underlying data model. diff --git a/codegen/target/generated-sources/src/models.rs b/codegen/target/generated-sources/src/models.rs index 66b667ca..467062c8 100644 --- a/codegen/target/generated-sources/src/models.rs +++ b/codegen/target/generated-sources/src/models.rs @@ -9,8 +9,7 @@ use std::collections::HashMap; use std::default::Default; use std::hash::Hash; -use chrono::DateTime; -use chrono::Utc; +use time::OffsetDateTime; fn deserialize_nonoptional_vec<'de, D: Deserializer<'de>, T: DeserializeOwned>( d: D, @@ -24,6 +23,28 @@ fn deserialize_nonoptional_map<'de, D: Deserializer<'de>, T: DeserializeOwned>( serde::Deserialize::deserialize(d).map(|x: Option<_>| x.unwrap_or(HashMap::new())) } +fn deserialize_timestamp<'de, D: Deserializer<'de>>( + d: D +) -> Result, D::Error> { + let opt: Option = serde::Deserialize::deserialize(d)?; + if let Some(s) = opt { + Ok(Some( + OffsetDateTime::parse(&s, &time::format_description::well_known::Rfc3339) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?, + )) + } else { + Ok(None) + } +} + +fn serialize_timestamp(date: &Option, s: S) -> Result { + match date { + Some(inner) => Ok(s.serialize_str(&inner.format(&time::format_description::well_known::Rfc3339) + .map_err(|e| serde::ser::Error::custom(format!("{:?}", e)))?)?), + None => Ok(s.serialize_str("")?) + } +} + /// Address represents an IPv4 or IPv6 IP address. #[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)] @@ -192,12 +213,14 @@ pub struct BuildCache { /// Date and time at which the build cache was created in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, /// Date and time at which the build cache was last used in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "LastUsedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub last_used_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub last_used_at: Option, #[serde(rename = "UsageCount")] #[serde(skip_serializing_if="Option::is_none")] @@ -269,12 +292,14 @@ pub struct ClusterInfo { /// Date and time at which the swarm was initialised in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, /// Date and time at which the swarm was last updated in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] @@ -333,11 +358,13 @@ pub struct Config { #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] @@ -1687,12 +1714,14 @@ pub struct HealthcheckResult { /// Date and time at which this check started in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "Start")] #[serde(skip_serializing_if="Option::is_none")] - pub start: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub start: Option, /// Date and time at which this check ended in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "End")] #[serde(skip_serializing_if="Option::is_none")] - pub end: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub end: Option, /// ExitCode meanings: - `0` healthy - `1` unhealthy - `2` reserved (considered unhealthy) - other values: error running probe #[serde(rename = "ExitCode")] @@ -1846,7 +1875,8 @@ pub struct ImageId { pub struct ImageMetadata { #[serde(rename = "LastTagTime")] #[serde(skip_serializing_if="Option::is_none")] - pub last_tag_time: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub last_tag_time: Option, } @@ -2370,7 +2400,8 @@ pub struct Network { #[serde(rename = "Created")] #[serde(skip_serializing_if="Option::is_none")] - pub created: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created: Option, #[serde(rename = "Scope")] #[serde(skip_serializing_if="Option::is_none")] @@ -2650,12 +2681,14 @@ pub struct Node { /// Date and time at which the node was added to the swarm in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, /// Date and time at which the node was last updated in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] @@ -3784,11 +3817,13 @@ pub struct Secret { #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] @@ -3837,11 +3872,13 @@ pub struct Service { #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] @@ -3918,7 +3955,8 @@ pub struct ServiceJobStatus { /// The last time, as observed by the server, that this job was started. #[serde(rename = "LastExecution")] #[serde(skip_serializing_if="Option::is_none")] - pub last_execution: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub last_execution: Option, } @@ -4296,11 +4334,13 @@ pub struct ServiceUpdateStatus { #[serde(rename = "StartedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub started_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub started_at: Option, #[serde(rename = "CompletedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub completed_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub completed_at: Option, #[serde(rename = "Message")] #[serde(skip_serializing_if="Option::is_none")] @@ -4942,7 +4982,7 @@ pub struct SystemInfo { #[serde(skip_serializing_if="Option::is_none")] pub experimental_build: Option, - /// Version string of the daemon. > **Note**: the [standalone Swarm API](https://docs.docker.com/swarm/swarm-api/) > returns the Swarm version instead of the daemon version, for example > `swarm/1.2.8`. + /// Version string of the daemon. > **Note**: the [standalone Swarm API](/swarm/swarm-api/) > returns the Swarm version instead of the daemon version, for example > `swarm/1.2.8`. #[serde(rename = "ServerVersion")] #[serde(skip_serializing_if="Option::is_none")] pub server_version: Option, @@ -5277,11 +5317,13 @@ pub struct Task { #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, /// Name of the task. #[serde(rename = "Name")] @@ -6004,7 +6046,8 @@ impl ::std::str::FromStr for TaskState { pub struct TaskStatus { #[serde(rename = "Timestamp")] #[serde(skip_serializing_if="Option::is_none")] - pub timestamp: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub timestamp: Option, #[serde(rename = "State")] #[serde(skip_serializing_if="Option::is_none")] @@ -6100,7 +6143,8 @@ pub struct Volume { /// Date/Time the volume was created. #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, /// Low-level details about the volume, provided by the volume driver. Details are returned as a map with key/value pairs: `{\"key\":\"value\",\"key2\":\"value2\"}`. The `Status` field is optional, and is omitted if the volume driver does not support this feature. #[serde(rename = "Status")] @@ -6699,12 +6743,14 @@ pub struct Swarm { /// Date and time at which the swarm was initialised in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "CreatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub created_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub created_at: Option, /// Date and time at which the swarm was last updated in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. #[serde(rename = "UpdatedAt")] #[serde(skip_serializing_if="Option::is_none")] - pub updated_at: Option>, + #[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")] + pub updated_at: Option, #[serde(rename = "Spec")] #[serde(skip_serializing_if="Option::is_none")] diff --git a/examples/hoover.rs b/examples/hoover.rs index a20e4d74..947833e0 100644 --- a/examples/hoover.rs +++ b/examples/hoover.rs @@ -5,7 +5,7 @@ use bollard::{ container::PruneContainersOptions, image::PruneImagesOptions, network::PruneNetworksOptions, volume::PruneVolumesOptions, }; -use chrono::{Duration, Utc}; +use time::{Duration, OffsetDateTime}; use std::collections::HashMap; @@ -15,8 +15,8 @@ const THRESHOLD_DAYS: i64 = 90; async fn main() -> Result<(), Box> { let docker = Docker::connect_with_socket_defaults().unwrap(); - let date = Utc::now() - Duration::days(THRESHOLD_DAYS); - let timestamp = &date.timestamp().to_string()[..]; + let date = OffsetDateTime::now_utc() - Duration::days(THRESHOLD_DAYS); + let timestamp = &date.unix_timestamp().to_string()[..]; let mut prune_filters = HashMap::new(); prune_filters.insert("until", vec![timestamp]); diff --git a/src/container.rs b/src/container.rs index c5ff50ad..974dee78 100644 --- a/src/container.rs +++ b/src/container.rs @@ -1,11 +1,11 @@ //! Container API: run docker containers and manage their lifecycle -use chrono::{DateTime, Utc}; use futures_core::Stream; use http::header::CONTENT_TYPE; use http::request::Builder; use hyper::{body::Bytes, Body, Method}; use serde::Serialize; +use time::OffsetDateTime; use std::cmp::Eq; use std::collections::HashMap; @@ -658,8 +658,16 @@ pub struct StorageStats { #[derive(Debug, Clone, Serialize, Deserialize)] #[allow(missing_docs)] pub struct Stats { - pub read: DateTime, - pub preread: DateTime, + #[serde( + deserialize_with = "crate::docker::deserialize_rfc3339", + serialize_with = "crate::docker::serialize_rfc3339" + )] + pub read: OffsetDateTime, + #[serde( + deserialize_with = "crate::docker::deserialize_rfc3339", + serialize_with = "crate::docker::serialize_rfc3339" + )] + pub preread: OffsetDateTime, pub num_procs: u32, pub pids_stats: PidsStats, pub network: Option, diff --git a/src/docker.rs b/src/docker.rs index ed2ec0ff..fd637b4e 100644 --- a/src/docker.rs +++ b/src/docker.rs @@ -15,7 +15,6 @@ use std::time::Duration; #[cfg(feature = "ct_logs")] use std::time::SystemTime; -use chrono::{DateTime, Utc}; use futures_core::Stream; use futures_util::future::FutureExt; use futures_util::future::TryFutureExt; @@ -30,6 +29,7 @@ use hyper_rustls::HttpsConnector; use hyperlocal::UnixConnector; #[cfg(feature = "ssl")] use rustls::sign::{CertifiedKey, RsaSigningKey}; +use time::OffsetDateTime; use tokio::io::{split, AsyncRead, AsyncWrite}; use tokio_util::codec::FramedRead; @@ -187,15 +187,34 @@ where ) } +pub fn deserialize_rfc3339<'de, D: serde::Deserializer<'de>>( + d: D, +) -> Result { + let s: String = serde::Deserialize::deserialize(d)?; + OffsetDateTime::parse(&s, &time::format_description::well_known::Rfc3339) + .map_err(|e| serde::de::Error::custom(format!("{:?}", e))) +} + +pub fn serialize_rfc3339( + date: &OffsetDateTime, + s: S, +) -> Result { + s.serialize_str( + &date + .format(&time::format_description::well_known::Rfc3339) + .map_err(|e| serde::ser::Error::custom(format!("{:?}", e)))?, + ) +} + pub(crate) fn serialize_as_timestamp( - opt: &Option>, + opt: &Option, s: S, ) -> Result where S: serde::Serializer, { match opt { - Some(t) => s.serialize_str(&format!("{}.{}", t.timestamp(), t.timestamp_subsec_nanos())), + Some(t) => s.serialize_str(&format!("{}.{}", t.unix_timestamp(), t.unix_timestamp_nanos())), None => s.serialize_str(""), } } @@ -403,7 +422,9 @@ impl Docker { let mut root_store = rustls::RootCertStore::empty(); for cert in rustls_native_certs::load_native_certs()? { - root_store.add(&rustls::Certificate(cert.0)).map_err(|err| NoNativeCertsError{ err })?; + root_store + .add(&rustls::Certificate(cert.0)) + .map_err(|err| NoNativeCertsError { err })?; } root_store.add_server_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.0.iter().map(|ta| { diff --git a/src/system.rs b/src/system.rs index 1fc97994..c06e7f72 100644 --- a/src/system.rs +++ b/src/system.rs @@ -1,11 +1,11 @@ //! System API: interface for interacting with the Docker server and/or Registry. -use chrono::{DateTime, Utc}; use futures_core::Stream; use http::request::Builder; use hyper::{Body, Method}; use serde::ser::Serialize; use serde_json::value::Value; +use time::OffsetDateTime; use std::collections::HashMap; use std::hash::Hash; @@ -103,15 +103,14 @@ pub struct VersionComponents { /// ## Examples /// /// ```rust -/// # extern crate chrono; /// use bollard::system::EventsOptions; -/// use chrono::{Duration, Utc}; +/// use time::{Duration, OffsetDateTime}; /// use std::collections::HashMap; /// /// # fn main() { /// EventsOptions::{ -/// since: Some(Utc::now() - Duration::minutes(20)), -/// until: Some(Utc::now()), +/// since: Some(OffsetDateTime::now_utc() - Duration::minutes(20)), +/// until: Some(OffsetDateTime::now_utc()), /// filters: HashMap::new() /// }; /// # } @@ -123,10 +122,10 @@ where { /// Show events created since this timestamp then stream new events. #[serde(serialize_with = "crate::docker::serialize_as_timestamp")] - pub since: Option>, + pub since: Option, /// Show events created until this timestamp then stop streaming. #[serde(serialize_with = "crate::docker::serialize_as_timestamp")] - pub until: Option>, + pub until: Option, /// A JSON encoded value of filters (a `map[string][]string`) to process on the event list. Available filters: /// - `config=` config name or ID /// - `container=` container name or ID @@ -250,15 +249,15 @@ impl Docker { /// /// ```rust /// use bollard::system::EventsOptions; - /// use chrono::{Duration, Utc}; + /// use time::{Duration, OffsetDateTime}; /// use std::collections::HashMap; /// /// # use bollard::Docker; /// # let docker = Docker::connect_with_http_defaults().unwrap(); /// /// docker.events(Some(EventsOptions:: { - /// since: Some(Utc::now() - Duration::minutes(20)), - /// until: Some(Utc::now()), + /// since: Some(OffsetDateTime::now_utc() - Duration::minutes(20)), + /// until: Some(OffsetDateTime::now_utc()), /// filters: HashMap::new(), /// })); /// ``` diff --git a/tests/system_test.rs b/tests/system_test.rs index 27c1b3cd..3d283fb8 100644 --- a/tests/system_test.rs +++ b/tests/system_test.rs @@ -5,11 +5,11 @@ use bollard::models::*; use bollard::system::*; use bollard::Docker; -use chrono::Utc; use futures_util::future; use futures_util::stream::select; use futures_util::stream::StreamExt; use futures_util::stream::TryStreamExt; +use time::OffsetDateTime; use tokio::runtime::Runtime; #[macro_use] @@ -81,7 +81,7 @@ async fn events_until_forever_test(docker: Docker) -> Result<(), Error> { format!("{}hello-world:linux", registry_http_addr()) }; - let start_time = Utc::now(); + let start_time = OffsetDateTime::now_utc(); let stream = docker.events(Some(EventsOptions:: { since: Some(start_time),