net_time/
lib.rs

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}