@@ -10,7 +10,7 @@ use std::io::{self, Cursor};
1010use std:: result;
1111
1212use curl:: easy:: { Easy , List } ;
13- use rustc_serialize:: json;
13+ use rustc_serialize:: json:: { self , Json } ;
1414
1515use url:: percent_encoding:: { percent_encode, QUERY_ENCODE_SET } ;
1616
@@ -39,6 +39,7 @@ pub enum Error {
3939 NotFound ,
4040 JsonEncodeError ( json:: EncoderError ) ,
4141 JsonDecodeError ( json:: DecoderError ) ,
42+ JsonParseError ( json:: ParserError ) ,
4243}
4344
4445impl From < json:: EncoderError > for Error {
@@ -53,6 +54,12 @@ impl From<json::DecoderError> for Error {
5354 }
5455}
5556
57+ impl From < json:: ParserError > for Error {
58+ fn from ( err : json:: ParserError ) -> Error {
59+ Error :: JsonParseError ( err)
60+ }
61+ }
62+
5663impl From < curl:: Error > for Error {
5764 fn from ( err : curl:: Error ) -> Error {
5865 Error :: Curl ( err)
@@ -78,6 +85,7 @@ pub struct NewCrate {
7885 pub homepage : Option < String > ,
7986 pub readme : Option < String > ,
8087 pub keywords : Vec < String > ,
88+ pub categories : Vec < String > ,
8189 pub license : Option < String > ,
8290 pub license_file : Option < String > ,
8391 pub repository : Option < String > ,
@@ -103,14 +111,17 @@ pub struct User {
103111 pub name : Option < String > ,
104112}
105113
114+ pub struct Warnings {
115+ pub invalid_categories : Vec < String > ,
116+ }
117+
106118#[ derive( RustcDecodable ) ] struct R { ok : bool }
107119#[ derive( RustcDecodable ) ] struct ApiErrorList { errors : Vec < ApiError > }
108120#[ derive( RustcDecodable ) ] struct ApiError { detail : String }
109121#[ derive( RustcEncodable ) ] struct OwnersReq < ' a > { users : & ' a [ & ' a str ] }
110122#[ derive( RustcDecodable ) ] struct Users { users : Vec < User > }
111123#[ derive( RustcDecodable ) ] struct TotalCrates { total : u32 }
112124#[ derive( RustcDecodable ) ] struct Crates { crates : Vec < Crate > , meta : TotalCrates }
113-
114125impl Registry {
115126 pub fn new ( host : String , token : Option < String > ) -> Registry {
116127 Registry :: new_handle ( host, token, Easy :: new ( ) )
@@ -147,7 +158,8 @@ impl Registry {
147158 Ok ( json:: decode :: < Users > ( & body) ?. users )
148159 }
149160
150- pub fn publish ( & mut self , krate : & NewCrate , tarball : & File ) -> Result < ( ) > {
161+ pub fn publish ( & mut self , krate : & NewCrate , tarball : & File )
162+ -> Result < Warnings > {
151163 let json = json:: encode ( krate) ?;
152164 // Prepare the body. The format of the upload request is:
153165 //
@@ -190,10 +202,24 @@ impl Registry {
190202 headers. append ( & format ! ( "Authorization: {}" , token) ) ?;
191203 self . handle . http_headers ( headers) ?;
192204
193- let _body = handle ( & mut self . handle , & mut |buf| {
205+ let body = handle ( & mut self . handle , & mut |buf| {
194206 body. read ( buf) . unwrap_or ( 0 )
195207 } ) ?;
196- Ok ( ( ) )
208+ // Can't derive RustcDecodable because JSON has a key named "crate" :(
209+ let response = if body. len ( ) > 0 {
210+ Json :: from_str ( & body) ?
211+ } else {
212+ Json :: from_str ( "{}" ) ?
213+ } ;
214+ let invalid_categories: Vec < String > =
215+ response
216+ . find_path ( & [ "warnings" , "invalid_categories" ] )
217+ . and_then ( Json :: as_array)
218+ . map ( |x| {
219+ x. iter ( ) . flat_map ( Json :: as_string) . map ( Into :: into) . collect ( )
220+ } )
221+ . unwrap_or_else ( Vec :: new) ;
222+ Ok ( Warnings { invalid_categories : invalid_categories } )
197223 }
198224
199225 pub fn search ( & mut self , query : & str , limit : u8 ) -> Result < ( Vec < Crate > , u32 ) > {
@@ -328,6 +354,7 @@ impl fmt::Display for Error {
328354 Error :: NotFound => write ! ( f, "cannot find crate" ) ,
329355 Error :: JsonEncodeError ( ref e) => write ! ( f, "json encode error: {}" , e) ,
330356 Error :: JsonDecodeError ( ref e) => write ! ( f, "json decode error: {}" , e) ,
357+ Error :: JsonParseError ( ref e) => write ! ( f, "json parse error: {}" , e) ,
331358 }
332359 }
333360}
0 commit comments