1extern crate curl;
2
3use std::error::Error;
4use std::path::Path;
5use std::time::Duration;
6use curl::easy::{Easy, List};
7use curl::easy::{IpResolve, ProxyType, SslVersion, TimeCondition};
8use curl::easy::{ReadError, WriteError};
9
10use super::errors::*;
11
12pub struct EasyBuilder {
20 easy: Easy,
21 errors: Vec<curl::Error>,
23}
24
25macro_rules! option_setter {
26 ( $meth:ident, $an:ident: $mt:ty ) => {
27 pub fn $meth(&mut self, $an: $mt) -> &mut EasyBuilder {
28 if let Err(e) = self.easy.$meth($an) {
29 self.errors.push(e);
30 }
31 self
32 }
33 };
34}
35
36macro_rules! path_opt {
37 ( $meth:ident, $an:ident ) => {
38 pub fn $meth<P: AsRef<Path>>(&mut self, $an: P) -> &mut EasyBuilder {
39 if let Err(e) = self.easy.$meth($an) {
40 self.errors.push(e);
41 }
42 self
43 }
44 };
45}
46
47impl EasyBuilder {
48
49 pub fn new() -> EasyBuilder {
58 EasyBuilder {
59 easy: Easy::new(),
60 errors: Vec::new(),
61 }
62 }
63
64 option_setter!(verbose, verbose: bool);
65 option_setter!(show_header, show: bool);
66 option_setter!(progress, progress: bool);
67 option_setter!(signal, signal: bool);
68 option_setter!(wildcard_match, m: bool);
69 option_setter!(fail_on_error, fail: bool);
70 option_setter!(url, url: &str);
71 option_setter!(port, port: u16);
72 option_setter!(proxy, url: &str);
73 option_setter!(proxy_port, port: u16);
74 option_setter!(proxy_type, kind: ProxyType);
75 option_setter!(noproxy, skip: &str);
76 option_setter!(http_proxy_tunnel, tunnel: bool);
77 option_setter!(interface, interface: &str);
78 option_setter!(set_local_port, port: u16);
79 option_setter!(local_port_range, range: u16);
80 option_setter!(dns_cache_timeout, dur: Duration);
81 option_setter!(buffer_size, size: usize);
82 option_setter!(tcp_nodelay, enable: bool);
83 option_setter!(address_scope, scope: u32);
84 option_setter!(username, user: &str);
85 option_setter!(password, pass: &str);
86 option_setter!(proxy_username, user: &str);
87 option_setter!(proxy_password, pass: &str);
88 option_setter!(autoreferer, enable: bool);
89 option_setter!(accept_encoding, encoding: &str);
90 option_setter!(transfer_encoding, enable: bool);
91 option_setter!(follow_location, enable: bool);
92 option_setter!(unrestricted_auth, enable: bool);
93 option_setter!(max_redirections, max: u32);
94 option_setter!(put, enable: bool);
95 option_setter!(post, enable: bool);
96 option_setter!(post_fields_copy, data: &[u8]);
97 option_setter!(post_field_size, size: u64);
98 option_setter!(referer, referer: &str);
99 option_setter!(useragent, useragent: &str);
100 option_setter!(http_headers, list: List);
101 option_setter!(cookie, cookie: &str);
102 path_opt!(cookie_file, file);
103 path_opt!(cookie_jar, file);
104 option_setter!(cookie_session, session: bool);
105 option_setter!(cookie_list, cookie: &str);
106 option_setter!(get, enable: bool);
107 option_setter!(ignore_content_length, ignore: bool);
108 option_setter!(http_content_decoding, enable: bool);
109 option_setter!(http_transfer_decoding, enable: bool);
110 option_setter!(range, range: &str);
111 option_setter!(resume_from, from: u64);
112 option_setter!(custom_request, request: &str);
113 option_setter!(fetch_filetime, fetch: bool);
114 option_setter!(nobody, enable: bool);
115 option_setter!(in_filesize, size: u64);
116 option_setter!(upload, enable: bool);
117 option_setter!(max_filesize, size: u64);
118 option_setter!(time_condition, cond: TimeCondition);
119 option_setter!(time_value, val: i64);
120 option_setter!(timeout, timeout: Duration);
121 option_setter!(low_speed_limit, limit: u32);
122 option_setter!(low_speed_time, dur: Duration);
123 option_setter!(max_send_speed, speed: u64);
124 option_setter!(max_recv_speed, speed: u64);
125 option_setter!(max_connects, max: u32);
126 option_setter!(fresh_connect, enable: bool);
127 option_setter!(forbid_reuse, enable: bool);
128 option_setter!(connect_timeout, timeout: Duration);
129 option_setter!(ip_resolve, resolve: IpResolve);
130 option_setter!(connect_only, enable: bool);
131 path_opt!(ssl_cert, cert);
132 option_setter!(ssl_cert_type, kind: &str);
133 path_opt!(ssl_key, key);
134 option_setter!(ssl_key_type, kind: &str);
135 option_setter!(key_password, password: &str);
136 option_setter!(ssl_engine, engine: &str);
137 option_setter!(ssl_engine_default, enable: bool);
138 option_setter!(ssl_version, version: SslVersion);
139 option_setter!(ssl_verify_host, verify: bool);
140 option_setter!(ssl_verify_peer, verify: bool);
141 path_opt!(cainfo, path);
142 path_opt!(issuer_cert, path);
143 path_opt!(capath, path);
144 path_opt!(crlfile, path);
145 option_setter!(certinfo, enable: bool);
146 path_opt!(random_file, p);
147 path_opt!(egd_socket, p);
148 option_setter!(ssl_cipher_list, ciphers: &str);
149 option_setter!(ssl_sessionid_cache, enable: bool);
150
151 pub fn write_function<F>(&mut self, f: F) -> &mut EasyBuilder
152 where F: FnMut(&[u8]) -> Result<usize, WriteError> + Send + 'static
153 {
154 if let Err(e) = self.easy.write_function(f) {
155 self.errors.push(e);
156 }
157 self
158 }
159
160 pub fn read_function<F>(&mut self, f: F) -> &mut EasyBuilder
161 where F: FnMut(&mut [u8]) -> Result<usize, ReadError> + Send + 'static
162 {
163 if let Err(e) = self.easy.read_function(f) {
164 self.errors.push(e);
165 }
166 self
167 }
168
169 pub fn has_errors(&self) -> bool {
171 !self.errors.is_empty()
172 }
173
174 pub fn result(&mut self) -> BuildResult<&mut Easy> {
185 if !self.has_errors() {
186 Ok(&mut self.easy)
187 } else {
188 let mut s = String::new();
189 for e in &self.errors {
190 s.push_str(e.description());
191 s.push('\n');
192 }
193 Err(BuildError::from(s))
194 }
195 }
196}