-
Notifications
You must be signed in to change notification settings - Fork 605
/
upload.rs
205 lines (180 loc) · 5.72 KB
/
upload.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
use std::collections::HashMap;
use std::ops::Deref;
use rustc_serialize::{Decodable, Decoder, Encoder, Encodable};
use semver;
use dependency::Kind as DependencyKind;
use keyword::Keyword as CrateKeyword;
use krate::Crate;
#[derive(RustcDecodable, RustcEncodable)]
pub struct NewCrate {
pub name: CrateName,
pub vers: CrateVersion,
pub deps: Vec<CrateDependency>,
pub features: HashMap<CrateName, Vec<Feature>>,
pub authors: Vec<String>,
pub description: Option<String>,
pub homepage: Option<String>,
pub documentation: Option<String>,
pub readme: Option<String>,
pub keywords: Option<KeywordList>,
pub license: Option<String>,
pub license_file: Option<String>,
pub repository: Option<String>,
}
#[derive(PartialEq, Eq, Hash)]
pub struct CrateName(pub String);
pub struct CrateVersion(pub semver::Version);
pub struct CrateVersionReq(pub semver::VersionReq);
pub struct KeywordList(pub Vec<Keyword>);
pub struct Keyword(pub String);
pub struct Feature(pub String);
#[derive(RustcDecodable, RustcEncodable)]
pub struct CrateDependency {
pub optional: bool,
pub default_features: bool,
pub name: CrateName,
pub features: Vec<Feature>,
pub version_req: CrateVersionReq,
pub target: Option<String>,
pub kind: Option<DependencyKind>,
}
impl Decodable for CrateName {
fn decode<D: Decoder>(d: &mut D) -> Result<CrateName, D::Error> {
let s = try!(d.read_str());
if !Crate::valid_name(&s) {
return Err(d.error(&format!("invalid crate name specified: {}", s)))
}
Ok(CrateName(s))
}
}
impl Decodable for Keyword {
fn decode<D: Decoder>(d: &mut D) -> Result<Keyword, D::Error> {
let s = try!(d.read_str());
if !CrateKeyword::valid_name(&s) {
return Err(d.error(&format!("invalid keyword specified: {}", s)))
}
Ok(Keyword(s))
}
}
impl Decodable for Feature {
fn decode<D: Decoder>(d: &mut D) -> Result<Feature, D::Error> {
let s = try!(d.read_str());
if !Crate::valid_feature_name(&s) {
return Err(d.error(&format!("invalid feature name specified: {}", s)))
}
Ok(Feature(s))
}
}
impl Decodable for CrateVersion {
fn decode<D: Decoder>(d: &mut D) -> Result<CrateVersion, D::Error> {
let s = try!(d.read_str());
match semver::Version::parse(&s) {
Ok(v) => Ok(CrateVersion(v)),
Err(..) => Err(d.error(&format!("invalid semver: {}", s))),
}
}
}
impl Decodable for CrateVersionReq {
fn decode<D: Decoder>(d: &mut D) -> Result<CrateVersionReq, D::Error> {
let s = try!(d.read_str());
match semver::VersionReq::parse(&s) {
Ok(v) => Ok(CrateVersionReq(v)),
Err(..) => Err(d.error(&format!("invalid version req: {}", s))),
}
}
}
impl Decodable for KeywordList {
fn decode<D: Decoder>(d: &mut D) -> Result<KeywordList, D::Error> {
let inner: Vec<Keyword> = try!(Decodable::decode(d));
if inner.len() > 5 {
return Err(d.error("a maximum of 5 keywords per crate are allowed"))
}
for val in inner.iter() {
if val.len() > 20 {
return Err(d.error("keywords must contain less than 20 \
characters"))
}
}
Ok(KeywordList(inner))
}
}
impl Decodable for DependencyKind {
fn decode<D: Decoder>(d: &mut D) -> Result<DependencyKind, D::Error> {
let s: String = try!(Decodable::decode(d));
match &s[..] {
"dev" => Ok(DependencyKind::Dev),
"build" => Ok(DependencyKind::Build),
"normal" => Ok(DependencyKind::Normal),
s => Err(d.error(&format!("invalid dependency kind `{}`, must be \
one of dev, build, or normal", s))),
}
}
}
impl Encodable for CrateName {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
d.emit_str(self)
}
}
impl Encodable for Keyword {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
d.emit_str(self)
}
}
impl Encodable for Feature {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
d.emit_str(self)
}
}
impl Encodable for CrateVersion {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
d.emit_str(&(**self).to_string())
}
}
impl Encodable for CrateVersionReq {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
d.emit_str(&(**self).to_string())
}
}
impl Encodable for KeywordList {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
let KeywordList(ref inner) = *self;
inner.encode(d)
}
}
impl Encodable for DependencyKind {
fn encode<E: Encoder>(&self, d: &mut E) -> Result<(), E::Error> {
match *self {
DependencyKind::Normal => "normal".encode(d),
DependencyKind::Build => "build".encode(d),
DependencyKind::Dev => "dev".encode(d),
}
}
}
impl Deref for CrateName {
type Target = str;
fn deref(&self) -> &str { &self.0 }
}
impl Deref for Keyword {
type Target = str;
fn deref(&self) -> &str { &self.0 }
}
impl Deref for Feature {
type Target = str;
fn deref(&self) -> &str { &self.0 }
}
impl Deref for CrateVersion {
type Target = semver::Version;
fn deref<'a>(&'a self) -> &'a semver::Version {
let CrateVersion(ref s) = *self; s
}
}
impl Deref for CrateVersionReq {
type Target = semver::VersionReq;
fn deref<'a>(&'a self) -> &'a semver::VersionReq {
let CrateVersionReq(ref s) = *self; s
}
}
impl Deref for KeywordList {
type Target = [Keyword];
fn deref(&self) -> &[Keyword] { &self.0 }
}