1use anyhow::{Context, Result};
2use serde_json::Value;
3
4pub enum Source {
5 Taobao,
6}
7
8impl Source {
9 fn to_url(&self) -> &'static str {
10 match self {
11 Source::Taobao => "http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp",
12 }
13 }
14
15 fn parse(&self, body: &str) -> Result<u64> {
16 match self {
17 Source::Taobao => {
18 let v: Value = serde_json::from_str(body).context("parse taobao msg into json")?;
19
20 let t = v
21 .get("data")
22 .and_then(|v| v.get("t"))
23 .context("get `t` from json taotao returned")?;
24
25 t.as_str()
26 .context("'t' returned by taobao is not a String")?
27 .parse()
28 .context("par `t` into u64")
29 }
30 }
31 }
32
33 pub fn get_timestamp(&self) -> Result<u64> {
34 let data = ureq::get(self.to_url())
35 .call()
36 .with_context(|| format!("call {} failed", self.to_url()))?
37 .into_string()
38 .with_context(|| {
39 format!(
40 "parse data returned by {} into string failed",
41 self.to_url()
42 )
43 })?;
44
45 self.parse(&data)
46 }
47}
48
49#[cfg(test)]
50mod test {
51 use super::*;
52
53 #[test]
54 fn test_ts_from_taobao() {
55 println!("{}", Source::Taobao.get_timestamp().unwrap());
56 }
57}