summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml3
-rw-r--r--examples/images.rs2
-rw-r--r--src/builder.rs148
-rw-r--r--src/errors.rs32
-rw-r--r--src/lib.rs129
-rw-r--r--src/rep.rs488
-rw-r--r--src/transport.rs6
7 files changed, 389 insertions, 419 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 974d6e2..42d978d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,16 +17,15 @@ http = "0.1"
hyper = "0.12"
hyper-openssl = "0.6"
hyperlocal = { version = "0.6", optional = true }
-jed = "0.1"
log = "0.4"
mime = "0.3"
openssl = "0.10"
-rustc-serialize = "0.3"
tar = "0.4"
tokio = "0.1"
url = "1.7"
serde = "1"
serde_derive = "1"
+serde_json = "1"
[dev-dependencies]
env_logger = "0.5"
diff --git a/examples/images.rs b/examples/images.rs
index 531cd02..195ea06 100644
--- a/examples/images.rs
+++ b/examples/images.rs
@@ -5,6 +5,6 @@ fn main() {
let images = docker.images().list(&Default::default()).unwrap();
println!("docker images in stock");
for i in images {
- println!("{:?}", i.RepoTags);
+ println!("{:?}", i.repo_tags);
}
}
diff --git a/src/builder.rs b/src/builder.rs
index ffc0cf1..0171a3e 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1,13 +1,15 @@
//! Interfaces for building various structures
use self::super::Result;
-use rustc_serialize::json::{self, Json, ToJson};
+use serde::Serialize;
+use serde_json::{self, Value, Number, map::Map};
use std::cmp::Eq;
use std::collections::{BTreeMap, HashMap};
use std::hash::Hash;
use std::iter::IntoIterator;
use std::iter::Peekable;
use url::form_urlencoded;
+use errors::Error;
#[derive(Default)]
pub struct PullOptions {
@@ -254,7 +256,7 @@ impl ContainerListOptionsBuilder {
}
// structure is a a json encoded object mapping string keys to a list
// of string values
- self.params.insert("filters", json::encode(&param).unwrap());
+ self.params.insert("filters", serde_json::to_string(&param).unwrap());
self
}
@@ -284,42 +286,22 @@ impl ContainerListOptionsBuilder {
}
/// Interface for building a new docker container from an existing image
+#[derive(Serialize)]
pub struct ContainerOptions {
pub name: Option<String>,
- params: HashMap<&'static str, Json>,
+ params: HashMap<&'static str, Value>,
params_list: HashMap<&'static str, Vec<String>>,
params_hash: HashMap<String, Vec<HashMap<String, String>>>,
}
-impl ToJson for ContainerOptions {
- fn to_json(&self) -> Json {
- let mut body_members = BTreeMap::new();
-
- // The HostConfig element gets initialized to an empty object,
- // for backward compatibility.
- body_members.insert(
- "HostConfig".to_string(),
- Json::Object(BTreeMap::new()),
- );
-
- let mut body = Json::Object(body_members);
-
- self.parse_from(&self.params, &mut body);
- self.parse_from(&self.params_list, &mut body);
- self.parse_from(&self.params_hash, &mut body);
-
- body
- }
-}
-
/// Function to insert a JSON value into a tree where the desired
/// location of the value is given as a path of JSON keys.
fn insert<'a, I, V>(
key_path: &mut Peekable<I>,
value: &V,
- parent_node: &mut Json,
+ parent_node: &mut Value,
) where
- V: ToJson,
+ V: Serialize,
I: Iterator<Item = &'a str>,
{
let local_key = key_path.next().unwrap();
@@ -329,13 +311,13 @@ fn insert<'a, I, V>(
.as_object_mut()
.unwrap()
.entry(local_key.to_string())
- .or_insert(Json::Object(BTreeMap::new()));
+ .or_insert(Value::Object(Map::new()));
insert(key_path, value, node);
} else {
parent_node.as_object_mut().unwrap().insert(
local_key.to_string(),
- value.to_json(),
+ serde_json::to_value(value).unwrap(),
);
}
}
@@ -348,17 +330,32 @@ impl ContainerOptions {
/// serialize options as a string. returns None if no options are defined
pub fn serialize(&self) -> Result<String> {
- Ok(json::encode(&self.to_json())?)
+ Ok(serde_json::to_string(&self.to_json())?)
+ }
+
+ fn to_json(&self) -> Value {
+ let mut body_members = Map::new();
+ // The HostConfig element gets initialized to an empty object,
+ // for backward compatibility.
+ body_members.insert(
+ "HostConfig".to_string(),
+ Value::Object(Map::new()),
+ );
+ let mut body = Value::Object(body_members);
+ self.parse_from(&self.params, &mut body);
+ self.parse_from(&self.params_list, &mut body);
+ self.parse_from(&self.params_hash, &mut body);
+ body
}
pub fn parse_from<'a, K, V>(
&self,
params: &'a HashMap<K, V>,
- body: &mut Json,
+ body: &mut Value,
) where
&'a HashMap<K, V>: IntoIterator,
K: ToString + Eq + Hash,
- V: ToJson,
+ V: Serialize,
{
for (k, v) in params.iter() {
let key_string = k.to_string();
@@ -370,7 +367,7 @@ impl ContainerOptions {
#[derive(Default)]
pub struct ContainerOptionsBuilder {
name: Option<String>,
- params: HashMap<&'static str, Json>,
+ params: HashMap<&'static str, Value>,
params_list: HashMap<&'static str, Vec<String>>,
params_hash: HashMap<String, Vec<HashMap<String, String>>>,
}
@@ -381,7 +378,7 @@ impl ContainerOptionsBuilder {
let params_list = HashMap::new();
let params_hash = HashMap::new();
- params.insert("Image", Json::String(image.to_owned()));
+ params.insert("Image", Value::String(image.to_owned()));
ContainerOptionsBuilder {
name: None,
params: params,
@@ -419,22 +416,22 @@ impl ContainerOptionsBuilder {
}
pub fn memory(&mut self, memory: u64) -> &mut ContainerOptionsBuilder {
- self.params.insert("HostConfig.Memory", Json::U64(memory));
+ self.params.insert("HostConfig.Memory", Value::Number(Number::from(memory)));
self
}
pub fn labels(&mut self, labels: &HashMap<&str, &str>) -> &mut ContainerOptionsBuilder {
- let mut json_labels : BTreeMap<String, Json> = BTreeMap::new();
+ let mut json_labels = Map::new();
for (k, v) in labels {
let key : &str = k.as_ref();
let value : &str = v.as_ref();
- json_labels.insert(key .to_owned(), Json::String(value.to_string()));
+ json_labels.insert(key .to_owned(), Value::String(value.to_string()));
}
self.params.insert(
"Labels",
- Json::Object(json_labels),
+ Value::Object(json_labels),
);
self
@@ -474,7 +471,7 @@ impl ContainerOptionsBuilder {
if !network.is_empty() {
self.params.insert(
"HostConfig.NetworkMode",
- Json::String(network.to_owned()),
+ Value::String(network.to_owned()),
);
}
self
@@ -505,7 +502,7 @@ impl ContainerOptionsBuilder {
if !entrypoint.is_empty() {
self.params.insert(
"Entrypoint",
- Json::String(entrypoint.to_owned()),
+ Value::String(entrypoint.to_owned()),
);
}
self
@@ -544,7 +541,7 @@ impl ContainerOptionsBuilder {
if !log_driver.is_empty() {
self.params.insert(
"HostConfig.LogConfig.Type",
- Json::String(log_driver.to_owned()),
+ Value::String(log_driver.to_owned()),
);
}
self
@@ -558,13 +555,13 @@ impl ContainerOptionsBuilder {
if !name.is_empty() {
self.params.insert(
"HostConfig.RestartPolicy.Name",
- Json::String(name.to_owned()),
+ Value::String(name.to_owned()),
);
}
if name == "on-failure" {
self.params.insert(
"HostConfig.RestartPolicy.MaximumRetryCount",
- Json::U64(maximum_retry_count),
+ Value::Number(Number::from(maximum_retry_count)),
);
}
self
@@ -580,6 +577,7 @@ impl ContainerOptionsBuilder {
}
}
+#[derive(Serialize)]
pub struct ExecContainerOptions {
params: HashMap<&'static str, Vec<String>>,
params_bool: HashMap<&'static str, bool>,
@@ -593,17 +591,7 @@ impl ExecContainerOptions {
/// serialize options as a string. returns None if no options are defined
pub fn serialize(&self) -> Result<String> {
- let mut body = BTreeMap::new();
-
- for (k, v) in &self.params {
- body.insert(k.to_string(), v.to_json());
- }
- for (k, v) in &self.params_bool {
- body.insert(k.to_string(), v.to_json());
- }
-
- let json_obj: Json = body.to_json();
- Ok(json::encode(&json_obj)?)
+ Ok(serde_json::to_string(self)?)
}
}
@@ -794,7 +782,7 @@ impl EventsOptionsBuilder {
};
}
- self.params.insert("filters", json::encode(&params).unwrap());
+ self.params.insert("filters", serde_json::to_string(&params).unwrap());
self
}
@@ -942,7 +930,7 @@ impl ImageListOptionsBuilder {
}
// structure is a a json encoded object mapping string keys to a list
// of string values
- self.params.insert("filters", json::encode(&param).unwrap());
+ self.params.insert("filters", serde_json::to_string(&param).unwrap());
self
}
@@ -1020,23 +1008,13 @@ impl NetworkListOptions {
}
/// Interface for creating new docker network
+#[derive(Serialize)]
pub struct NetworkCreateOptions {
pub name: Option<String>,
params: HashMap<&'static str, String>,
params_hash: HashMap<String, Vec<HashMap<String, String>>>,
}
-impl ToJson for NetworkCreateOptions {
- fn to_json(&self) -> Json {
- let mut body: BTreeMap<String, Json> = BTreeMap::new();
-
- self.parse_from(&self.params, &mut body);
- self.parse_from(&self.params_hash, &mut body);
-
- body.to_json()
- }
-}
-
impl NetworkCreateOptions {
/// return a new instance of a builder for options
pub fn builder(name: &str) -> NetworkCreateOptionsBuilder {
@@ -1045,21 +1023,21 @@ impl NetworkCreateOptions {
/// serialize options as a string. returns None if no options are defined
pub fn serialize(&self) -> Result<String> {
- Ok(json::encode(&self.to_json())?)
+ serde_json::to_string(self).map_err(Error::from)
}
pub fn parse_from<'a, K, V>(
&self,
params: &'a HashMap<K, V>,
- body: &mut BTreeMap<String, Json>,
+ body: &mut BTreeMap<String, Value>,
) where
&'a HashMap<K, V>: IntoIterator,
K: ToString + Eq + Hash,
- V: ToJson,
+ V: Serialize,
{
for (k, v) in params.iter() {
let key = k.to_string();
- let value = v.to_json();
+ let value = serde_json::to_value(v).unwrap();
body.insert(key, value);
}
@@ -1116,38 +1094,30 @@ impl NetworkCreateOptionsBuilder {
}
/// Interface for connect container to network
+#[derive(Serialize)]
pub struct ContainerConnectionOptions {
- pub Container: Option<String>,
+ pub container: Option<String>,
params: HashMap<&'static str, String>,
}
-impl ToJson for ContainerConnectionOptions {
- fn to_json(&self) -> Json {
- let mut body: BTreeMap<String, Json> = BTreeMap::new();
- self.parse_from(&self.params, &mut body);
- body.to_json()
- }
-}
-
-
impl ContainerConnectionOptions {
/// serialize options as a string. returns None if no options are defined
pub fn serialize(&self) -> Result<String> {
- Ok(json::encode(&self.to_json())?)
+ serde_json::to_string(self).map_err(Error::from)
}
pub fn parse_from<'a, K, V>(
&self,
params: &'a HashMap<K, V>,
- body: &mut BTreeMap<String, Json>,
+ body: &mut BTreeMap<String, Value>,
) where
&'a HashMap<K, V>: IntoIterator,
K: ToString + Eq + Hash,
- V: ToJson,
+ V: Serialize,
{
for (k, v) in params.iter() {
let key = k.to_string();
- let value = v.to_json();
+ let value = serde_json::to_value(v).unwrap();
body.insert(key, value);
}
@@ -1157,7 +1127,7 @@ impl ContainerConnectionOptions {
let mut params = HashMap::new();
params.insert("Container", container_id.to_owned());
ContainerConnectionOptions {
- Container: None,
+ container: None,
params: params.clone(),
}
}
@@ -1165,7 +1135,7 @@ impl ContainerConnectionOptions {
pub fn force(&mut self) -> ContainerConnectionOptions {
self.params.insert("Force", "true".to_owned());
ContainerConnectionOptions {
- Container: None,
+ container: None,
params: self.params.clone(),
}
}
@@ -1230,8 +1200,10 @@ mod tests {
.restart_policy("on-failure", 10)
.build();
- assert_eq!(r#"{"HostConfig":{"RestartPolicy":{"MaximumRetryCount":10,"Name":"on-failure"}},"Image":"test_image"}"#,
- options.serialize().unwrap());
+ assert_eq!(
+ r#"{"HostConfig":{"RestartPolicy":{"MaximumRetryCount":10,"Name":"on-failure"}},"Image":"test_image"}"#,
+ options.serialize().unwrap()
+ );
options = ContainerOptionsBuilder::new("test_image")
.restart_policy("always", 0)
diff --git a/src/errors.rs b/src/errors.rs
index d4905a1..44be52a 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -2,37 +2,23 @@
use http;
use hyper::{self, StatusCode};
-use rustc_serialize::json::{DecoderError, EncoderError, ParserError};
+use serde_json::Error as SerdeError;
use std::error::Error as ErrorTrait;
use std::fmt;
use std::io::Error as IoError;
#[derive(Debug)]
pub enum Error {
- Decoding(DecoderError),
- Encoding(EncoderError),
- Parse(ParserError),
+ SerdeJsonError(SerdeError),
Hyper(hyper::Error),
Http(http::Error),
IO(IoError),
Fault { code: StatusCode, message: String },
}
-impl From<ParserError> for Error {
- fn from(error: ParserError) -> Error {
- Error::Parse(error)
- }
-}
-
-impl From<DecoderError> for Error {
- fn from(error: DecoderError) -> Error {
- Error::Decoding(error)
- }
-}
-
-impl From<EncoderError> for Error {
- fn from(error: EncoderError) -> Error {
- Error::Encoding(error)
+impl From<SerdeError> for Error {
+ fn from(error: SerdeError) -> Error {
+ Error::SerdeJsonError(error)
}
}
@@ -58,9 +44,7 @@ impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Docker Error: ")?;
match self {
- &Error::Decoding(ref err) => return err.fmt(f),
- &Error::Encoding(ref err) => return err.fmt(f),
- &Error::Parse(ref err) => return err.fmt(f),
+ &Error::SerdeJsonError(ref err) => return err.fmt(f),
&Error::Http(ref err) => return err.fmt(f),
&Error::Hyper(ref err) => return err.fmt(f),
&Error::IO(ref err) => return err.fmt(f),
@@ -76,9 +60,7 @@ impl ErrorTrait for Error {
fn cause(&self) -> Option<&ErrorTrait> {
match self {
- &Error::Decoding(ref err) => Some(err),
- &Error::Encoding(ref err) => Some(err),
- &Error::Parse(ref err) => Some(err),
+ &Error::SerdeJsonError(ref err) => Some(err),
&Error::Http(ref err) => Some(err),
&Error::IO(ref err) => Some(err),
_ => None,
diff --git a/src/lib.rs b/src/lib.rs
index c2f7807..ef8a8f7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,7 +9,7 @@
//! let images = docker.images().list(&Default::default()).unwrap();
//! println!("docker images in stock");
//! for i in images {
-//! println!("{:?}", i.RepoTags);
+//! println!("{:?}", i.repo_tags);
//! }
//! ```
@@ -22,15 +22,14 @@ extern crate hyper;
extern crate hyper_openssl;
#[cfg(feature = "unix-socket")]
extern crate hyperlocal;
-extern crate jed;
extern crate mime;
extern crate openssl;
-extern crate rustc_serialize;
extern crate tar;
extern crate url;
#[macro_use]
extern crate serde_derive;
extern crate serde;
+extern crate serde_json;
extern crate tokio;
pub mod builder;
@@ -63,12 +62,11 @@ use rep::{
Version,
};
use rep::{NetworkCreateInfo, NetworkDetails as NetworkInfo};
-use rustc_serialize::json::{self, Json};
+use serde_json::Value;
use std::borrow::Cow;
use std::cell::RefCell;
use std::env;
use std::io::prelude::*;
-use std::iter::IntoIterator;
use std::path::Path;
use std::time::Duration;
use transport::{tar, Transport};
@@ -106,7 +104,7 @@ impl<'a, 'b> Image<'a, 'b> {
let raw = self
.docker
.get(&format!("/images/{}/json", self.name)[..])?;
- Ok(json::decode::<ImageDetails>(&raw)?)
+ Ok(serde_json::from_str::<ImageDetails>(&raw)?)
}
/// Lists the history of the images set of changes
@@ -114,25 +112,25 @@ impl<'a, 'b> Image<'a, 'b> {
let raw = self
.docker
.get(&format!("/images/{}/history", self.name)[..])?;
- Ok(json::decode::<Vec<History>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<History>>(&raw)?)
}
/// Delete's an image
pub fn delete(&self) -> Result<Vec<Status>> {
let raw = self.docker.delete(&format!("/images/{}", self.name)[..])?;
- Ok(match Json::from_str(&raw)? {
- Json::Array(ref xs) => xs.iter().map(|j| {
+ Ok(match serde_json::from_str(&raw)? {
+ Value::Array(ref xs) => xs.iter().map(|j| {
let obj = j.as_object().expect("expected json object");
obj.get("Untagged")
.map(|sha| {
Status::Untagged(
- sha.as_string()
+ sha.as_str()
.expect("expected Untagged to be a string")
.to_owned(),
)
}).or(obj.get("Deleted").map(|sha| {
Status::Deleted(
- sha.as_string()
+ sha.as_str()
.expect("expected Deleted to be a string")
.to_owned(),
)
@@ -164,7 +162,7 @@ impl<'a> Images<'a> {
pub fn build(
&self,
opts: &BuildOptions,
- ) -> Result<Box<Iterator<Item = Json>>> {
+ ) -> Result<Vec<Value>> {
let mut path = vec!["/build".to_owned()];
if let Some(query) = opts.serialize() {
path.push(query)
@@ -174,11 +172,12 @@ impl<'a> Images<'a> {
tarball::dir(&mut bytes, &opts.path[..])?;
- let raw = self
+ self
.docker
- .stream_post(&path.join("?"), Some((Body::from(bytes), tar())))?;
- let it = jed::Iter::new(raw).into_iter();
- Ok(Box::new(it))
+ .stream_post(&path.join("?"), Some((Body::from(bytes), tar())))
+ .and_then(|r| {
+ serde_json::from_reader::<_, Vec<Value>>(r).map_err(Error::from)
+ })
}
/// Lists the docker images on the current docker host
@@ -188,7 +187,7 @@ impl<'a> Images<'a> {
path.push(query);
}
let raw = self.docker.get(&path.join("?"))?;
- Ok(json::decode::<Vec<ImageRep>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<ImageRep>>(&raw)?)
}
/// Returns a reference to a set of operations available for a named image
@@ -202,21 +201,23 @@ impl<'a> Images<'a> {
.append_pair("term", term)
.finish();
let raw = self.docker.get(&format!("/images/search?{}", query)[..])?;
- Ok(json::decode::<Vec<SearchResult>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<SearchResult>>(&raw)?)
}
/// Pull and create a new docker images from an existing image
pub fn pull(
&self,
opts: &PullOptions,
- ) -> Result<Box<Iterator<Item = Json>>> {
+ ) -> Result<Vec<Value>> {
let mut path = vec!["/images/create".to_owned()];
if let Some(query) = opts.serialize() {
path.push(query);
}
- let raw = self.docker.stream_post::<Body>(&path.join("?"), None)?;
- let it = jed::Iter::new(raw).into_iter();
- Ok(Box::new(it))
+ self.docker
+ .stream_post::<Body>(&path.join("?"), None)
+ .and_then(|r| {
+ serde_json::from_reader::<_, Vec<Value>>(r).map_err(Error::from)
+ })
}
/// exports a collection of named images,
@@ -263,7 +264,7 @@ impl<'a, 'b> Container<'a, 'b> {
let raw = self
.docker
.get(&format!("/containers/{}/json", self.id)[..])?;
- Ok(json::decode::<ContainerDetails>(&raw)?)
+ Ok(serde_json::from_str::<ContainerDetails>(&raw)?)
}
/// Returns a `top` view of information about the container process
@@ -277,7 +278,7 @@ impl<'a, 'b> Container<'a, 'b> {
}
let raw = self.docker.get(&path.join("?"))?;
- Ok(json::decode::<Top>(&raw)?)
+ Ok(serde_json::from_str::<Top>(&raw)?)
}
/// Returns a stream of logs emitted but the container instance
@@ -294,7 +295,7 @@ impl<'a, 'b> Container<'a, 'b> {
let raw = self
.docker
.get(&format!("/containers/{}/changes", self.id)[..])?;
- Ok(json::decode::<Vec<Change>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<Change>>(&raw)?)
}
/// Exports the current docker container into a tarball
@@ -304,17 +305,13 @@ impl<'a, 'b> Container<'a, 'b> {
}
/// Returns a stream of stats specific to this container instance
- pub fn stats(&self) -> Result<Box<Iterator<Item = Stats>>> {
- let raw = self
+ pub fn stats(&self) -> Result<Vec<Stats>> {
+ self
.docker
- .stream_get(&format!("/containers/{}/stats", self.id)[..])?;
- let it = jed::Iter::new(raw).into_iter().map(|j| {
- // fixme: better error handling
- debug!("{:?}", j);
- let s = json::encode(&j).unwrap();
- json::decode::<Stats>(&s).unwrap()
- });
- Ok(Box::new(it))
+ .stream_get(&format!("/containers/{}/stats", self.id)[..])
+ .and_then(|r|{
+ serde_json::from_reader::<_, Vec<Stats>>(r).map_err(Error::from)
+ })
}
/// Start the container instance
@@ -392,7 +389,7 @@ impl<'a, 'b> Container<'a, 'b> {
let raw = self
.docker
.post::<Body>(&format!("/containers/{}/wait", self.id)[..], None)?;
- Ok(json::decode::<Exit>(&raw)?)
+ Ok(serde_json::from_str::<Exit>(&raw)?)
}
/// Delete the container instance
@@ -426,19 +423,25 @@ impl<'a, 'b> Container<'a, 'b> {
Ok(res) => {
let data = "{}";
let mut bytes = data.as_bytes();
- self.docker
- .stream_post(
- &format!(
- "/exec/{}/start",
- Json::from_str(res.as_str())
- .unwrap()
- .search("Id")
- .unwrap()
- .as_string()
- .unwrap()
- )[..],
- Some((bytes, mime::APPLICATION_JSON)),
- ).map(|stream| Tty::new(stream))
+ let json: Value = serde_json::from_str(res.as_str())?;
+
+ if let Value::Object(ref obj) = json {
+ self.docker
+ .stream_post(
+ &format!(
+ "/exec/{}/start",
+ obj
+ .get("Id")
+ .unwrap()
+ .as_str()
+ .unwrap()
+ )[..],
+ Some((bytes, mime::APPLICATION_JSON)),
+ ).map(|stream| Tty::new(stream))
+ } else {
+ // TODO
+ panic!()
+ }
}
}
}
@@ -467,7 +470,7 @@ impl<'a> Containers<'a> {
path.push(query)
}
let raw = self.docker.get(&path.join("?"))?;
- Ok(json::decode::<Vec<ContainerRep>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<ContainerRep>>(&raw)?)
}
/// Returns a reference to a set of operations available to a specific container instance
@@ -480,7 +483,7 @@ impl<'a> Containers<'a> {
&'a self,
opts: &ContainerOptions,
) -> Result<ContainerCreateInfo> {
- let data = opts.serialize()?;
+ let data = serde_json::to_string(opts)?;
let bytes = data.into_bytes();
let mut path = vec!["/containers/create".to_owned()];
@@ -495,7 +498,7 @@ impl<'a> Containers<'a> {
let raw = self
.docker
.post(&path.join("?"), Some((bytes, mime::APPLICATION_JSON)))?;
- Ok(json::decode::<ContainerCreateInfo>(&raw)?)
+ Ok(serde_json::from_str::<ContainerCreateInfo>(&raw)?)
}
}
@@ -517,7 +520,7 @@ impl<'a> Networks<'a> {
path.push(query);
}
let raw = self.docker.get(&path.join("?"))?;
- Ok(json::decode::<Vec<NetworkInfo>>(&raw)?)
+ Ok(serde_json::from_str::<Vec<NetworkInfo>>(&raw)?)
}
/// Returns a reference to a set of operations available to a specific network instance
@@ -536,7 +539,7 @@ impl<'a> Networks<'a> {
let raw = self
.docker
.post(&path.join("?"), Some((bytes, mime::APPLICATION_JSON)))?;
- Ok(json::decode::<NetworkCreateInfo>(&raw)?)
+ Ok(serde_json::from_str::<NetworkCreateInfo>(&raw)?)
}
}
@@ -566,7 +569,7 @@ impl<'a, 'b> Network<'a, 'b> {
/// Inspects the current docker network instance's details
pub fn inspect(&self) -> Result<NetworkInfo> {
let raw = self.docker.get(&format!("/networks/{}", self.id)[..])?;
- Ok(json::decode::<NetworkInfo>(&raw)?)
+ Ok(serde_json::from_str::<NetworkInfo>(&raw)?)
}
/// Delete the network instance
@@ -729,13 +732,13 @@ impl Docker {
/// Returns version information associated with the docker daemon
pub fn version(&self) -> Result<Version> {
let raw = self.get("/version")?;
- Ok(json::decode::<Version>(&raw)?)
+ Ok(serde_json::from_str::<Version>(&raw)?)
}
/// Returns information associated with the docker daemon
pub fn info(&self) -> Result<Info> {
let raw = self.get("/info")?;
- Ok(json::decode::<Info>(&raw)?)
+ Ok(serde_json::from_str::<Info>(&raw)?)
}
/// Returns a simple ping response indicating the docker daemon is accessible
@@ -747,19 +750,13 @@ impl Docker {
pub fn events(
&self,
opts: &EventsOptions,
- ) -> Result<Box<Iterator<Item = Event>>> {
+ ) -> Result<Vec<Event>> {
let mut path = vec!["/events".to_owned()];
if let Some(query) = opts.serialize() {
path.push(query);
}
- let raw = self.stream_get(&path.join("?")[..])?;
- let it = jed::Iter::new(raw).into_iter().map(|j| {
- debug!("{:?}", j);
- // fixme: better error handling
- let s = json::encode(&j).unwrap();
- json::decode::<Event>(&s).unwrap()
- });
- Ok(Box::new(it))
+ self.stream_get(&path.join("?")[..])
+ .and_then(|r| serde_json::from_reader::<_, Vec<Event>>(r).map_err(Error::from))
}
fn get(&self, endpoint: &str) -> Result<String> {
diff --git a/src/rep.rs b/src/rep.rs
index 9375350..92cbe02 100644
--- a/src/rep.rs
+++ b/src/rep.rs
@@ -2,7 +2,7 @@
use std::collections::HashMap;
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SearchResult {
pub description: String,
pub is_official: bool,
@@ -11,172 +11,184 @@ pub struct SearchResult {
pub star_count: u64,
}
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-#[allow(non_snake_case)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct Image {
- pub Created: u64,
- pub Id: String,
- pub ParentId: String,
- pub Labels: Option<HashMap<String, String>>,
- pub RepoTags: Option<Vec<String>>,
- pub RepoDigests: Option<Vec<String>>,
- pub VirtualSize: u64,
+ pub created: u64,
+ pub id: String,
+ pub parent_id: String,
+ pub labels: Option<HashMap<String, String>>,
+ pub repo_tags: Option<Vec<String>>,
+ pub repo_digests: Option<Vec<String>>,
+ pub virtual_size: u64,
}
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-#[allow(non_snake_case)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct ImageDetails {
- pub Architecture: String,
- pub Author: String,
- pub Comment: String,
- pub Config: Config,
- pub Created: String,
- pub DockerVersion: String,
- pub Id: String,
- pub Os: String,
- pub Parent: String,
- pub Size: u64,
- pub VirtualSize: u64,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
-#[allow(non_snake_case)]
+ pub architecture: String,
+ pub author: String,
+ pub comment: String,
+ pub config: Config,
+ pub created: String,
+ pub docker_version: String,
+ pub id: String,
+ pub os: String,
+ pub parent: String,
+ pub size: u64,
+ pub virtual_size: u64,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct Container {
- pub Created: u64,
- pub Command: String,
- pub Id: String,
- pub Image: String,
- pub Labels: HashMap<String, String>,
- pub Names: Vec<String>,
- pub Ports: Vec<Port>,
- pub Status: String,
- pub SizeRw: Option<u64>,
- pub SizeRootFs: Option<u64>,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
-#[allow(non_snake_case)]
+ pub created: u64,
+ pub command: String,
+ pub id: String,
+ pub image: String,
+ pub labels: HashMap<String, String>,
+ pub names: Vec<String>,
+ pub ports: Vec<Port>,
+ pub status: String,
+ pub size_rw: Option<u64>,
+ pub size_root_fs: Option<u64>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct ContainerDetails {
- pub AppArmorProfile: String,
- pub Args: Vec<String>,
- pub Config: Config,
- pub Created: String,
- pub Driver: String,
+ pub app_armor_profile: String,
+ pub args: Vec<String>,
+ pub config: Config,
+ pub created: String,
+ pub driver: String,
// pub ExecIDs: ??
- pub HostConfig: HostConfig,
- pub HostnamePath: String,
- pub HostsPath: String,
- pub LogPath: String,
- pub Id: String,
- pub Image: String,
- pub MountLabel: String,
- pub Name: String,
- pub NetworkSettings: NetworkSettings,
- pub Path: String,
- pub ProcessLabel: String,
- pub ResolvConfPath: String,
- pub RestartCount: u64,
- pub State: State,
- pub Mounts: Vec<Mount>,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
-#[allow(non_snake_case)]
+ pub host_config: HostConfig,
+ pub hostname_path: String,
+ pub hosts_path: String,
+ pub log_path: String,
+ pub id: String,
+ pub image: String,
+ pub mount_label: String,
+ pub name: String,
+ pub network_settings: NetworkSettings,
+ pub path: String,
+ pub process_label: String,
+ pub resolv_conf_path: String,
+ pub restart_count: u64,
+ pub state: State,
+ pub mounts: Vec<Mount>,
+}
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct Mount {
- pub Source: String,
- pub Destination: String,
- pub Mode: String,
- pub RW: bool,
+ pub source: String,
+ pub destination: String,
+ pub mode: String,
+ #[serde(rename = "RW")]
+ pub rw: bool,
}
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
-#[allow(non_snake_case)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "PascalCase")]
pub struct State {
- pub Error: String,
- pub ExitCode: u64,
- pub FinishedAt: String,
- pub OOMKilled: bool,
- pub Paused: bool,
- pub Pid: u64,
- pub Restarting: bool,
- pub Running: bool,
- pub StartedAt: String,
-}
-
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable, Serialize, Deserialize)]
-#[allow(non_snake_case)]
+ pub error: String,
+ pub exit_code: u64,
+ pub finished_at: String,
+ #[serde(rename = "OOMKilled")]
+ pub oom_killed: bool,