use client::{Body, HttpClient};
use data::{self, HasDataPath, DeletedResult, XDataType, XErrorMessage};
use std::io::{self, Read};
use error::{self, Error, ApiError};
use rustc_serialize::json;
#[derive(RustcDecodable, Debug)]
pub struct FileAdded {
pub result: String
}
#[derive(RustcDecodable, Debug)]
pub struct FileDeleted {
pub result: DeletedResult
}
pub struct DataResponse {
data: Box<Read>,
}
impl Read for DataResponse {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.data.read(buf)
}
}
pub struct DataFile {
path: String,
client: HttpClient,
}
impl HasDataPath for DataFile {
fn new(client: HttpClient, path: &str) -> Self { DataFile { client: client, path: data::parse_data_uri(path).to_string() } }
fn path(&self) -> &str { &self.path }
fn client(&self) -> &HttpClient { &self.client }
}
impl DataFile {
pub fn put<'a, B: Into<Body<'a>>>(&'a self, body: B) -> Result<FileAdded, Error> {
let url = self.to_url();
let req = self.client.put(url).body(body);
let mut res = try!(req.send());
let mut res_json = String::new();
try!(res.read_to_string(&mut res_json));
match res.status.is_success() {
true => json::decode(&res_json).map_err(|err| err.into()),
false => Err(error::decode(&res_json)),
}
}
pub fn get(&self) -> Result<DataResponse, Error> {
let url = self.to_url();
let req = self.client.get(url);
let res = try!(req.send());
if res.status.is_success() {
if let Some(data_type) = res.headers.get::<XDataType>() {
if "file" != data_type.to_string() {
return Err(Error::DataTypeError(format!("Expected file, Received {}", data_type)));
}
}
Ok(DataResponse{
data: Box::new(res),
})
} else {
let msg = match res.headers.get::<XErrorMessage>() {
Some(err_header) => format!("{}: {}", res.status, err_header),
None => format!("{}", res.status),
};
Err(ApiError{message: msg, stacktrace: None}.into())
}
}
pub fn delete(&self) -> Result<FileDeleted, Error> {
let url = self.to_url();
let req = self.client.delete(url);
let mut res = try!(req.send());
let mut res_json = String::new();
try!(res.read_to_string(&mut res_json));
match res.status.is_success() {
true => json::decode(&res_json).map_err(|err| err.into()),
false => Err(error::decode(&res_json)),
}
}
}