oclc/
client.rs

1use crate::api_models::*;
2use crate::models::{ClassifyResult, Result};
3use log::info;
4use reqwest::{Client, ClientBuilder};
5use serde_xml_rs::from_str;
6
7pub struct OclcClient {
8    client: Client,
9}
10
11impl OclcClient {
12    pub fn new() -> Result<Self> {
13        info!("building client");
14        let client = ClientBuilder::new().build()?;
15        info!("built client");
16        Ok(OclcClient { client })
17    }
18
19    pub fn new_with_client(client: Client) -> Self {
20        OclcClient { client }
21    }
22
23    pub async fn lookup(&self, stdnbr: String) -> Result<Option<ClassifyResult>> {
24        let uri = format!(
25            "http://classify.oclc.org/classify2/Classify?stdnbr={}&summary=true",
26            stdnbr
27        );
28        info!("looking up {}", uri);
29        let response = self.client.get(uri).send().await?.text().await?;
30        info!("got: {}", response);
31        let classify: Classify = from_str(&response)?;
32        info!("got classify: {:?}", classify);
33        classify.into()
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use anyhow::anyhow;
41
42    #[tokio::test]
43    async fn not_found() -> Result<()> {
44        let client = OclcClient::new()?;
45        let result = client.lookup("foo".to_string()).await?;
46        assert_eq!(result, None);
47        Ok(())
48    }
49
50    #[tokio::test]
51    async fn found() -> anyhow::Result<()> {
52        let client = OclcClient::new()?;
53        let result = client.lookup("0679442723".to_string()).await?;
54        assert_eq!(result.is_some(), true);
55        let mut works = match result {
56            Some(ClassifyResult::MultiWork(multi_work)) => multi_work.works,
57            _ => return Err(anyhow!("not a multi work")),
58        };
59        works.sort();
60        let mut expected = vec![
61            Work {
62                author: "Dibdin, Michael".to_string(),
63                editions: "66".to_string(),
64                format: "Book".to_string(),
65                holdings: "1278".to_string(),
66                hyr: Some("2020".to_string()),
67                itemtype: "itemtype-book".to_string(),
68                lyr: Some("1996".to_string()),
69                owi: "570898".to_string(),
70                schemes: Some("DDC LCC".to_string()),
71                title: "Così fan tutti : an Aurelio Zen mystery".to_string(),
72                wi: Some("570898".to_string()),
73            },
74            Work {
75                author: "Dibdin, Michael".to_string(),
76                editions: "1".to_string(),
77                format: "Book".to_string(),
78                holdings: "2".to_string(),
79                hyr: Some("1997".to_string()),
80                itemtype: "itemtype-book".to_string(),
81                lyr: Some("1996".to_string()),
82                owi: "10033458423".to_string(),
83                schemes: Some("DDC".to_string()),
84                title: "Cosi fan tutti".to_string(),
85                wi: Some("10033458423".to_string()),
86            },
87        ];
88        expected.sort();
89        assert_eq!(works, expected);
90        Ok(())
91    }
92}