1#![allow(dead_code)]
2
3extern crate curl;
4extern crate rustc_serialize;
5extern crate url;
6
7use curl::http;
8use curl::http::handle::Method;
9use rustc_serialize::base64::{STANDARD, ToBase64};
10use rustc_serialize::json::Json;
11use std::fmt::Display;
12use std::str::from_utf8;
13use url::form_urlencoded::serialize;
14
15pub use error::{Error, ErrorKind};
16
17mod error;
18mod macros;
19
20pub mod resources {
21 mod account;
22 mod application_fees;
23 mod balance;
24 mod bitcoin_receivers;
25 mod charges;
26 mod coupons;
27 mod customers;
28 mod events;
29 mod file_uploads;
30 mod invoice_items;
31 mod invoices;
32 mod plans;
33 mod recipients;
34 mod tokens;
35 mod transfers;
36}
37
38const VERSION: &'static str = env!("CARGO_PKG_VERSION");
39
40const API_BASE: &'static str = "https://api.stripe.com";
41const BASE_PATH: &'static str = "/v1";
42const CONNECT_BASE: &'static str = "https://connect.stripe.com";
43const UPLOADS_BASE: &'static str = "https://uploads.stripe.com";
44
45pub static mut api_key: Option<*const str> = None;
46pub static mut api_version: Option<*const str> = None;
47
48pub fn set_api_key(val: &str) {
49 unsafe { api_key = Some(val) };
50}
51
52pub fn set_api_version(val: &str) {
53 unsafe { api_key = Some(val) };
54}
55
56pub struct Params<'a> {
57 pairs: Vec<(String, String)>,
58 content_type: &'a str,
59}
60
61impl<'a> Params<'a> {
62 pub fn new() -> Self {
63 Params { pairs: Vec::new(), content_type: "application/x-www-form-urlencoded" }
65 }
66
67 pub fn set<T>(&mut self, key: &str, val: T) where T: Display {
68 self.pairs.push((key.to_string(), val.to_string()));
69 }
70
71 fn to_body(&self) -> String {
72 serialize(self.pairs.iter().map(|&(ref n, ref v)| (&**n, &**v)))
73 }
74}
75
76pub type Response = Result<Json, Error>;
77
78fn request(method: Method, path: &str, params: Option<&Params>) -> Response {
79 let body = params.and_then(|b| Some(b.to_body()));
80 let mut handle = http::handle();
81 let mut req = match method {
82 Method::Get => handle.get(path),
83 Method::Post => handle.post(path, body.as_ref().map_or("", |b| &b))
84 .content_type("application/x-www-form-urlencoded"),
85 Method::Delete => handle.delete(path),
86 _ => panic!("unknown method"),
87 };
88
89 unsafe {
90 let auth = match api_key {
91 Some(val) => format!("{}:", &*val).as_bytes().to_base64(STANDARD),
92 None => return Err(Error::new(ErrorKind::AuthentificationError,
93 "No API Key provided")),
94 };
95 req = req.header("Authorization", &format!("Basic {}", auth))
96 .header("Accept", "application/json")
97 .header("User-Agent", &format!("Stripe{} RustBindings/{}", BASE_PATH, VERSION));
98
99 if api_version.is_some() {
100 req = req.header("Stripe-Version", &*api_version.unwrap());
101 }
102
103 }
105
106 let resp = try!(req.exec());
107 let body = try!(from_utf8(resp.get_body()));
108 let result = try!(Json::from_str(body));
109
110 if let Some(val) = result.find("error") {
111 return Err(Error::from_json(val, resp.get_code()));
112 }
113
114 Ok(result)
115}