Skip to content
Permalink
Browse files

feat: use chrono to deserialize date times

  • Loading branch information...
schrieveslaach committed Sep 3, 2019
1 parent 779ac24 commit f5532c7cf3175d23b87fcc4a6e4d910962603fdd
Showing with 107 additions and 2 deletions.
  1. +4 −0 CHANGELOG.md
  2. +2 −1 Cargo.toml
  3. +2 −1 examples/images.rs
  4. +40 −0 src/builder.rs
  5. +59 −0 src/rep.rs
@@ -1,3 +1,7 @@
# 0.6.0

* add chrono as an optional feature [#190](https://github.com/softprops/shiplift/pull/190)

# 0.5.0

* make tls an optional dependency [#130](https://github.com/softprops/shiplift/pull/130)
@@ -21,6 +21,7 @@ maintenance = { status = "actively-developed" }
base64 = "0.10"
byteorder = "1.3.1"
bytes = "0.4"
chrono = { version = "0.4", optional = true, features = ["serde"] }
flate2 = "1.0"
futures = "0.1"
http = "0.1"
@@ -42,6 +43,6 @@ url = "1.7"
env_logger = "0.6"

[features]
default = ["unix-socket", "tls"]
default = ["chrono", "unix-socket", "tls"]
unix-socket = ["hyperlocal"]
tls = ["openssl", "hyper-openssl"]
@@ -10,8 +10,9 @@ fn main() {
.map(|images| {
for i in images {
println!(
"{} {:?}",
"{} {} {:?}",
i.id,
i.created,
i.repo_tags.unwrap_or_else(|| vec!["none".into()])
);
}
@@ -1190,6 +1190,20 @@ impl LogsOptionsBuilder {
self
}

#[cfg(feature = "chrono")]
pub fn since<Tz>(
&mut self,
timestamp: &chrono::DateTime<Tz>,
) -> &mut Self
where
Tz: chrono::TimeZone,
{
self.params
.insert("since", timestamp.timestamp().to_string());
self
}

#[cfg(not(feature = "chrono"))]
pub fn since(
&mut self,
timestamp: i64,
@@ -1712,6 +1726,32 @@ mod tests {
);
}

#[cfg(feature = "chrono")]
#[test]
fn logs_options() {
let timestamp = chrono::NaiveDateTime::from_timestamp(2_147_483_647, 0);
let since = chrono::DateTime::<chrono::Utc>::from_utc(timestamp, chrono::Utc);

let options = LogsOptionsBuilder::default()
.follow(true)
.stdout(true)
.stderr(true)
.timestamps(true)
.tail("all")
.since(&since)
.build();

let serialized = options.serialize().unwrap();

assert!(serialized.contains("follow=true"));
assert!(serialized.contains("stdout=true"));
assert!(serialized.contains("stderr=true"));
assert!(serialized.contains("timestamps=true"));
assert!(serialized.contains("tail=all"));
assert!(serialized.contains("since=2147483647"));
}

#[cfg(not(feature = "chrono"))]
#[test]
fn logs_options() {
let options = LogsOptionsBuilder::default()
@@ -1,5 +1,7 @@
//! Rust representations of docker json structures

#[cfg(feature = "chrono")]
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

@@ -15,6 +17,10 @@ pub struct SearchResult {
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Image {
#[cfg(feature = "chrono")]
#[serde(deserialize_with = "datetime_from_unix_timestamp")]
pub created: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created: u64,
pub id: String,
pub parent_id: String,
@@ -31,6 +37,9 @@ pub struct ImageDetails {
pub author: String,
pub comment: String,
pub config: Config,
#[cfg(feature = "chrono")]
pub created: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created: String,
pub docker_version: String,
pub id: String,
@@ -43,6 +52,10 @@ pub struct ImageDetails {
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Container {
#[cfg(feature = "chrono")]
#[serde(deserialize_with = "datetime_from_unix_timestamp")]
pub created: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created: u64,
pub command: String,
pub id: String,
@@ -61,6 +74,9 @@ pub struct ContainerDetails {
pub app_armor_profile: String,
pub args: Vec<String>,
pub config: Config,
#[cfg(feature = "chrono")]
pub created: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created: String,
pub driver: String,
// pub ExecIDs: ??
@@ -96,13 +112,19 @@ pub struct Mount {
pub struct State {
pub error: String,
pub exit_code: u64,
#[cfg(feature = "chrono")]
pub finished_at: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub finished_at: String,
#[serde(rename = "OOMKilled")]
pub oom_killed: bool,
pub paused: bool,
pub pid: u64,
pub restarting: bool,
pub running: bool,
#[cfg(feature = "chrono")]
pub started_at: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub started_at: String,
}

@@ -420,6 +442,10 @@ pub struct ContainerCreateInfo {
#[serde(rename_all = "PascalCase")]
pub struct History {
pub id: String,
#[cfg(feature = "chrono")]
#[serde(deserialize_with = "datetime_from_unix_timestamp")]
pub created: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created: u64,
pub created_by: String,
}
@@ -441,7 +467,15 @@ pub struct Event {
pub status: Option<String>,
pub id: Option<String>,
pub from: Option<String>,
#[cfg(feature = "chrono")]
#[serde(deserialize_with = "datetime_from_unix_timestamp")]
pub time: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub time: u64,
#[cfg(feature = "chrono")]
#[serde(deserialize_with = "datetime_from_nano_timestamp", rename = "timeNano")]
pub time_nano: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
#[serde(rename = "timeNano")]
pub time_nano: u64,
}
@@ -476,6 +510,9 @@ pub struct Volumes {
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Volume {
#[cfg(feature = "chrono")]
pub created_at: DateTime<Utc>,
#[cfg(not(feature = "chrono"))]
pub created_at: String,
pub driver: String,
pub labels: Option<HashMap<String, String>>,
@@ -484,3 +521,25 @@ pub struct Volume {
pub options: Option<HashMap<String, String>>,
pub scope: String,
}

#[cfg(feature = "chrono")]
fn datetime_from_unix_timestamp<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: serde::Deserializer<'de>,
{
let timestamp = chrono::NaiveDateTime::from_timestamp(i64::deserialize(deserializer)?, 0);
Ok(DateTime::<Utc>::from_utc(timestamp, Utc))
}

#[cfg(feature = "chrono")]
fn datetime_from_nano_timestamp<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
where
D: serde::Deserializer<'de>,
{
let timestamp_nano = u64::deserialize(deserializer)?;
let timestamp = chrono::NaiveDateTime::from_timestamp(
(timestamp_nano / 1_000_000_000) as i64,
(timestamp_nano % 1_000_000_000) as u32,
);
Ok(DateTime::<Utc>::from_utc(timestamp, Utc))
}

0 comments on commit f5532c7

Please sign in to comment.
You can’t perform that action at this time.