@@ -10,7 +10,7 @@ use std::io::{self, Cursor};
10
10
use std:: result;
11
11
12
12
use curl:: easy:: { Easy , List } ;
13
- use rustc_serialize:: json;
13
+ use rustc_serialize:: json:: { self , Json } ;
14
14
15
15
use url:: percent_encoding:: { percent_encode, QUERY_ENCODE_SET } ;
16
16
@@ -39,6 +39,7 @@ pub enum Error {
39
39
NotFound ,
40
40
JsonEncodeError ( json:: EncoderError ) ,
41
41
JsonDecodeError ( json:: DecoderError ) ,
42
+ JsonParseError ( json:: ParserError ) ,
42
43
}
43
44
44
45
impl From < json:: EncoderError > for Error {
@@ -53,6 +54,12 @@ impl From<json::DecoderError> for Error {
53
54
}
54
55
}
55
56
57
+ impl From < json:: ParserError > for Error {
58
+ fn from ( err : json:: ParserError ) -> Error {
59
+ Error :: JsonParseError ( err)
60
+ }
61
+ }
62
+
56
63
impl From < curl:: Error > for Error {
57
64
fn from ( err : curl:: Error ) -> Error {
58
65
Error :: Curl ( err)
@@ -78,6 +85,7 @@ pub struct NewCrate {
78
85
pub homepage : Option < String > ,
79
86
pub readme : Option < String > ,
80
87
pub keywords : Vec < String > ,
88
+ pub categories : Vec < String > ,
81
89
pub license : Option < String > ,
82
90
pub license_file : Option < String > ,
83
91
pub repository : Option < String > ,
@@ -103,14 +111,17 @@ pub struct User {
103
111
pub name : Option < String > ,
104
112
}
105
113
114
+ pub struct Warnings {
115
+ pub invalid_categories : Vec < String > ,
116
+ }
117
+
106
118
#[ derive( RustcDecodable ) ] struct R { ok : bool }
107
119
#[ derive( RustcDecodable ) ] struct ApiErrorList { errors : Vec < ApiError > }
108
120
#[ derive( RustcDecodable ) ] struct ApiError { detail : String }
109
121
#[ derive( RustcEncodable ) ] struct OwnersReq < ' a > { users : & ' a [ & ' a str ] }
110
122
#[ derive( RustcDecodable ) ] struct Users { users : Vec < User > }
111
123
#[ derive( RustcDecodable ) ] struct TotalCrates { total : u32 }
112
124
#[ derive( RustcDecodable ) ] struct Crates { crates : Vec < Crate > , meta : TotalCrates }
113
-
114
125
impl Registry {
115
126
pub fn new ( host : String , token : Option < String > ) -> Registry {
116
127
Registry :: new_handle ( host, token, Easy :: new ( ) )
@@ -147,7 +158,8 @@ impl Registry {
147
158
Ok ( json:: decode :: < Users > ( & body) ?. users )
148
159
}
149
160
150
- pub fn publish ( & mut self , krate : & NewCrate , tarball : & File ) -> Result < ( ) > {
161
+ pub fn publish ( & mut self , krate : & NewCrate , tarball : & File )
162
+ -> Result < Warnings > {
151
163
let json = json:: encode ( krate) ?;
152
164
// Prepare the body. The format of the upload request is:
153
165
//
@@ -190,10 +202,24 @@ impl Registry {
190
202
headers. append ( & format ! ( "Authorization: {}" , token) ) ?;
191
203
self . handle . http_headers ( headers) ?;
192
204
193
- let _body = handle ( & mut self . handle , & mut |buf| {
205
+ let body = handle ( & mut self . handle , & mut |buf| {
194
206
body. read ( buf) . unwrap_or ( 0 )
195
207
} ) ?;
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 } )
197
223
}
198
224
199
225
pub fn search ( & mut self , query : & str , limit : u8 ) -> Result < ( Vec < Crate > , u32 ) > {
@@ -328,6 +354,7 @@ impl fmt::Display for Error {
328
354
Error :: NotFound => write ! ( f, "cannot find crate" ) ,
329
355
Error :: JsonEncodeError ( ref e) => write ! ( f, "json encode error: {}" , e) ,
330
356
Error :: JsonDecodeError ( ref e) => write ! ( f, "json decode error: {}" , e) ,
357
+ Error :: JsonParseError ( ref e) => write ! ( f, "json parse error: {}" , e) ,
331
358
}
332
359
}
333
360
}
0 commit comments