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
use std::fs::File;
use std::time::Duration;
use ast::{Defs, Def, Expr, DefEntry};
use std::io::Read;
use std::rc::Rc;
use json;
static URL: &'static str = "https://blockchain.info/stats?format=json";
pub fn parse(mut f: File) -> Result<Defs, String> {
let mut buf = String::new();
try!(f.read_to_string(&mut buf).map_err(|x| format!("{}", x)));
let parsed = try!(json::parse(&*buf).map_err(|x| format!("{}", x)));
let mut out = vec![];
if let Some(price) = parsed["market_price_usd"].as_number() {
let (sign, mantissa, exp) = price.as_parts();
let integer = format!("{}{}", if sign { "" } else { "-" }, mantissa);
if let Ok(price) = ::Number::from_parts(&*integer, None, Some(&*format!("{}", exp))) {
out.push(DefEntry {
name: "BTC".to_owned(),
def: Rc::new(Def::Unit(
Expr::Mul(vec![
Expr::Const(price),
Expr::Unit("USD".to_owned())
]))),
doc: Some(format!("Sourced from blockchain.info.")),
category: Some("currencies".to_owned()),
});
}
}
Ok(Defs {
defs: out
})
}
pub fn load() -> Result<Defs, String> {
::cached("btc.json", URL, Duration::from_secs(3*60*60)).and_then(parse)
}