oclc/
models.rs

1use crate::api_models::*;
2use thiserror::Error;
3use serde::{Serialize, Deserialize};
4
5pub type Result<A> = std::result::Result<A, ClassifyError>;
6
7#[derive(Debug, PartialEq)]
8pub enum ClassifyResult {
9    SingleWorkSummary(Box<SingleWorkSummary>),
10    //SingleWorkDetail(SingleWorkDetail),
11    MultiWork(MultiWork),
12}
13
14#[derive(Error, Debug)]
15pub enum ClassifyError {
16    #[error("No input. The method requires an input argument.")]
17    NoInput,
18    #[error("Invalid input. The standard number argument is invalid.")]
19    InvalidInput,
20    #[error("Unexpected error.")]
21    UnexpectedError,
22    #[error("Unexpected response code.")]
23    UnexpectedResponseCode,
24    #[error("Parsing Error: {0}")]
25    XmlParsingError(#[from] serde_xml_rs::Error),
26    #[error("Network Error: {0}")]
27    IoError(#[from] reqwest::Error),
28}
29
30#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
31pub struct ClassificationRecommendation {
32    most_popular: Vec<String>,
33    most_recent: Vec<String>,
34    latest_edition: Vec<String>,
35}
36
37#[derive(Debug, PartialEq, Serialize, Deserialize)]
38pub struct Recommendations {
39    pub dewie_decimal: ClassificationRecommendation,
40    pub library_of_congress: ClassificationRecommendation,
41}
42
43#[derive(Debug, PartialEq, Serialize, Deserialize)]
44pub struct SingleWorkSummary {
45    pub work: Work,
46    pub recommendations: Recommendations,
47}
48
49#[derive(Debug, PartialEq, Serialize, Deserialize)]
50pub struct MultiWork {
51    pub works: Vec<Work>,
52}
53
54fn push_if_some<A>(c: &mut Vec<A>, opts: Vec<Option<A>>) {
55    for opt in opts.into_iter().flatten() {
56        c.push(opt)
57    }
58}
59
60impl From<crate::api_models::RecommendationDataHolder> for ClassificationRecommendation {
61    fn from(recommendations: crate::api_models::RecommendationDataHolder) -> Self {
62        let mut result = ClassificationRecommendation::default();
63        for recommendation in recommendations.recommendations {
64            match recommendation {
65                RecommendationData::MostPopular(most_popular) => push_if_some(
66                    &mut result.most_popular,
67                    vec![most_popular.nsfa, most_popular.sfa],
68                ),
69                RecommendationData::MostRecent(most_recent) => push_if_some(
70                    &mut result.most_recent,
71                    vec![most_recent.nsfa, most_recent.sfa],
72                ),
73                RecommendationData::LatestEdition(latest_edition) => push_if_some(
74                    &mut result.latest_edition,
75                    vec![latest_edition.nsfa, latest_edition.sfa],
76                ),
77            }
78        }
79        result
80    }
81}
82
83impl From<crate::api_models::Recommendations> for Recommendations {
84    fn from(recommendations: crate::api_models::Recommendations) -> Self {
85        Recommendations {
86            dewie_decimal: recommendations.ddc.into(),
87            library_of_congress: recommendations.lcc.into(),
88        }
89    }
90}
91
92impl From<Classify> for SingleWorkSummary {
93    fn from(classify: Classify) -> Self {
94        SingleWorkSummary {
95            work: classify.work.unwrap(),
96            recommendations: classify.recommendations.unwrap().into(),
97        }
98    }
99}
100
101impl From<Classify> for MultiWork {
102    fn from(classify: Classify) -> Self {
103        MultiWork {
104            works: classify.works.unwrap().works,
105        }
106    }
107}
108
109impl From<Classify> for Result<Option<ClassifyResult>> {
110    fn from(classify: Classify) -> Self {
111        match classify.response.code {
112            100 => Err(ClassifyError::NoInput),
113            101 => Err(ClassifyError::InvalidInput),
114            102 => Ok(None),
115            0 => Ok(Some(ClassifyResult::SingleWorkSummary(Box::new(
116                classify.into(),
117            )))),
118            4 => Ok(Some(ClassifyResult::MultiWork(classify.into()))),
119            _ => Err(ClassifyError::UnexpectedResponseCode),
120        }
121    }
122}