Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use chrono to deserialize date times #190

Merged
merged 1 commit into from Sep 14, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -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))
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.