We're a place where coders share, stay up-to-date and grow their careers.
Aaaand Rust :)
Really an overkill for this task but fun nevertheless!
extern crate chrono; extern crate csv; extern crate futures; extern crate hyper; extern crate hyper_tls; extern crate serde; #[macro_use] extern crate serde_derive; extern crate serde_json; extern crate tokio_core; use futures::prelude::*; use futures::future::ok; use tokio_core::reactor::Core; use hyper::client::Client; use hyper_tls::HttpsConnector; use chrono::{DateTime, FixedOffset}; use std::collections::HashMap; use csv::Writer; use std::fs::File; #[derive(Debug, Deserialize, Clone)] struct Record { name: String, email: Option<String>, city: Option<String>, mac: String, timestamp: String, creditcard: Option<String>, } #[derive(Debug, Clone)] struct RecordParsed { record: Record, ts: DateTime<FixedOffset>, } const FORMAT: &'static str = "%Y%m%d"; fn main() { let mut core = Core::new().unwrap(); let client = Client::configure() .connector(HttpsConnector::new(4, &core.handle()).unwrap()) .build(&core.handle()); let uri = "https://gist.githubusercontent.com/jorinvo/7f19ce95a9a842956358/raw/e319340c2f6691f9cc8d8cc57ed532b5093e3619/data.json" .parse() .unwrap(); let fut = client.get(uri).and_then(move |resp| { resp.body().concat2().and_then(move |body| { let array: Vec<Record> = serde_json::from_slice(&body as &[u8]).unwrap(); let mut a_parsed: HashMap<String, Vec<RecordParsed>> = HashMap::new(); array .into_iter() .filter(|item| item.creditcard.is_some()) .map(|item| { let dt = DateTime::parse_from_str(&item.timestamp, "%Y-%m-%d %H:%M:%S %z").unwrap(); let rp = RecordParsed { record: item, ts: dt, }; let date_only = format!("{}.csv", rp.ts.format(FORMAT).to_string()); let ret = match a_parsed.get_mut(&date_only) { Some(ar) => { ar.push(rp); None } None => { let mut ar: Vec<RecordParsed> = Vec::new(); ar.push(rp); Some(ar) } }; if let Some(ar) = ret { a_parsed.insert(date_only, ar); } }) .collect::<()>(); a_parsed .iter() .map(|(key, array)| { println!("generating file == {:?}", key); let file = File::create(key).unwrap(); let mut wr = Writer::from_writer(file); array .iter() .map(|record| { let creditcard = match record.record.creditcard { Some(ref c) => c, None => panic!("should have filtered those!"), }; wr.write_record(&[&record.record.name, creditcard]).unwrap(); }) .collect::<()>(); }) .collect::<()>(); ok(()) }) }); core.run(fut).unwrap(); }
Aaaand Rust :)
Really an overkill for this task but fun nevertheless!