Skip to content

Commit

Permalink
Migrate from chrono to time 0.3
Browse files Browse the repository at this point in the history
  • Loading branch information
fussybeaver committed Jun 11, 2022
1 parent 79ea9ce commit 4d06b1e
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 59 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Expand Up @@ -24,9 +24,8 @@ ct_logs = ["ssl", "ct-logs"]

[dependencies]
base64 = "0.13"
bollard-stubs = { version = "=1.42.0-rc.2" }
bollard-stubs = { version = "=1.42.0-rc.2", path = "codegen/target/generated-sources" }
bytes = "1"
chrono = { version = "0.4", features = ["serde"] }
ct-logs = { version = "0.9.0", optional = true }
dirs-next = { version = "2.0", optional = true }
futures-core = "0.3"
Expand All @@ -46,6 +45,7 @@ serde_json = "1.0"
serde_urlencoded = "0.7"
tokio = { version = "1.7", features = ["time", "net", "io-util"] }
thiserror = "1.0"
time = { version = "0.3", features = ["formatting", "parsing"] }
tokio-util = { version = "0.7", features = ["codec"] }
url = "2.2"
webpki-roots = { version = "0.22", optional = true }
Expand Down
6 changes: 4 additions & 2 deletions codegen/src/main/java/bollard/BollardCodegen.java
Expand Up @@ -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
Expand Down Expand Up @@ -123,9 +124,10 @@ public Map<String, Object> postProcessAllModels(Map<String, Object> 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<Utc>";
prop.vendorExtensions.put("x-rustgen-is-datetime", true);
prop.datatype = "OffsetDateTime";
}
if (prop.isEnum) {
if (enumToString.contains(model.classname)) {
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/main/resources/bollard/Cargo.mustache
Expand Up @@ -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"
31 changes: 27 additions & 4 deletions codegen/src/main/resources/bollard/models.mustache
Expand Up @@ -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,
Expand All @@ -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<Option<OffsetDateTime>, D::Error> {
let opt: Option<String> = 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<S: Serializer>(date: &Option<OffsetDateTime>, s: S) -> Result<S::Ok, S::Error> {
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.
Expand Down Expand Up @@ -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<String, {{#items}}{{{datatype}}}{{/items}}>{{/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<String, {{#items}}{{{datatype}}}{{/items}}>{{/isContainer}}{{^isContainer}}{{{datatype}}}{{/isContainer}}{{/isListContainer}}{{/isEnum}}{{#vendorExtensions}}{{/vendorExtensions}}>,
{{/required}}

Expand Down
2 changes: 1 addition & 1 deletion codegen/target/generated-sources/Cargo.toml
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion codegen/target/generated-sources/README.md
Expand Up @@ -9,7 +9,7 @@ To see how to make this your own, look here:

- API version: 1.42.0-rc.2
- Code generation suffix: 1.42.0-rc.2
- Build date: 2022-05-31T18:04:02.348+01:00
- Build date: 2022-06-11T11:56:09.243+01:00

This autogenerated project defines an API crate `bollard-stubs` which contains:
* Data types representing the underlying data model.
Expand Down
100 changes: 73 additions & 27 deletions codegen/target/generated-sources/src/models.rs
Expand Up @@ -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,
Expand All @@ -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<Option<OffsetDateTime>, D::Error> {
let opt: Option<String> = 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<S: Serializer>(date: &Option<OffsetDateTime>, s: S) -> Result<S::Ok, S::Error> {
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)]
Expand Down Expand Up @@ -94,12 +115,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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

/// 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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub last_used_at: Option<OffsetDateTime>,

#[serde(rename = "UsageCount")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -171,12 +194,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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

/// 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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -235,11 +260,13 @@ pub struct Config {

#[serde(rename = "CreatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

#[serde(rename = "UpdatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -1695,12 +1722,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<chrono::DateTime<chrono::Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub start: Option<OffsetDateTime>,

/// 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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub end: Option<OffsetDateTime>,

/// ExitCode meanings: - `0` healthy - `1` unhealthy - `2` reserved (considered unhealthy) - other values: error running probe
#[serde(rename = "ExitCode")]
Expand Down Expand Up @@ -2334,7 +2363,8 @@ pub struct ImageInspectMetadata {
/// Date and time at which the image was last tagged in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds. This information is only available if the image was tagged locally, and omitted otherwise.
#[serde(rename = "LastTagTime")]
#[serde(skip_serializing_if="Option::is_none")]
pub last_tag_time: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub last_tag_time: Option<OffsetDateTime>,

}

Expand Down Expand Up @@ -2934,7 +2964,8 @@ pub struct Network {

#[serde(rename = "Created")]
#[serde(skip_serializing_if="Option::is_none")]
pub created: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created: Option<OffsetDateTime>,

#[serde(rename = "Scope")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -3241,12 +3272,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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

/// 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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -4425,11 +4458,13 @@ pub struct Secret {

#[serde(rename = "CreatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

#[serde(rename = "UpdatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -4478,11 +4513,13 @@ pub struct Service {

#[serde(rename = "CreatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

#[serde(rename = "UpdatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -4559,7 +4596,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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub last_execution: Option<OffsetDateTime>,

}

Expand Down Expand Up @@ -4937,11 +4975,13 @@ pub struct ServiceUpdateStatus {

#[serde(rename = "StartedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub started_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub started_at: Option<OffsetDateTime>,

#[serde(rename = "CompletedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub completed_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub completed_at: Option<OffsetDateTime>,

#[serde(rename = "Message")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -5027,12 +5067,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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

/// 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<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

#[serde(rename = "Spec")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -6017,11 +6059,13 @@ pub struct Task {

#[serde(rename = "CreatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

#[serde(rename = "UpdatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub updated_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub updated_at: Option<OffsetDateTime>,

/// Name of the task.
#[serde(rename = "Name")]
Expand Down Expand Up @@ -6744,7 +6788,8 @@ impl ::std::str::FromStr for TaskState {
pub struct TaskStatus {
#[serde(rename = "Timestamp")]
#[serde(skip_serializing_if="Option::is_none")]
pub timestamp: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub timestamp: Option<OffsetDateTime>,

#[serde(rename = "State")]
#[serde(skip_serializing_if="Option::is_none")]
Expand Down Expand Up @@ -6840,7 +6885,8 @@ pub struct Volume {
/// Date/Time the volume was created.
#[serde(rename = "CreatedAt")]
#[serde(skip_serializing_if="Option::is_none")]
pub created_at: Option<DateTime<Utc>>,
#[serde(default, deserialize_with = "deserialize_timestamp", serialize_with = "serialize_timestamp")]
pub created_at: Option<OffsetDateTime>,

/// 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")]
Expand Down
6 changes: 3 additions & 3 deletions examples/hoover.rs
Expand Up @@ -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;

Expand All @@ -15,8 +15,8 @@ const THRESHOLD_DAYS: i64 = 90;
async fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
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]);
Expand Down

0 comments on commit 4d06b1e

Please sign in to comment.