crossref/query/
members.rs

1use crate::error::Result;
2use crate::query::works::{WorksCombiner, WorksFilter, WorksIdentQuery, WorksQuery};
3use crate::query::*;
4use std::borrow::Cow;
5
6/// filters supported for the `/members` route
7#[derive(Debug, Clone)]
8pub enum MembersFilter {
9    /// Member has made their references public for one or more of their prefixes
10    HasPublicReferences,
11    /// metadata for works where references are either `open`, `limited` (to Metadata Plus subscribers) or `closed`
12    ReferenceVisibility(Visibility),
13    /// count of DOIs for material published more than two years ago
14    BlackfileDoiCount(i32),
15    /// count of DOIs for material published within last two years
16    CurrentDoiCount(i32),
17}
18
19impl MembersFilter {
20    /// the key name for the filter element
21    pub fn name(&self) -> &str {
22        match self {
23            MembersFilter::HasPublicReferences => "has-public-references",
24            MembersFilter::ReferenceVisibility(_) => "reference-visibility",
25            MembersFilter::BlackfileDoiCount(_) => "blackfile-doi-count",
26            MembersFilter::CurrentDoiCount(_) => "current-doi-count",
27        }
28    }
29}
30
31impl ParamFragment for MembersFilter {
32    fn key(&self) -> Cow<str> {
33        Cow::Borrowed(self.name())
34    }
35
36    fn value(&self) -> Option<Cow<str>> {
37        match self {
38            MembersFilter::HasPublicReferences => None,
39            MembersFilter::ReferenceVisibility(vis) => Some(Cow::Borrowed(vis.as_str())),
40            MembersFilter::BlackfileDoiCount(num) => Some(Cow::Owned(num.to_string())),
41            MembersFilter::CurrentDoiCount(num) => Some(Cow::Owned(num.to_string())),
42        }
43    }
44}
45
46impl Filter for MembersFilter {}
47
48impl_common_query!(MembersQuery, MembersFilter);
49
50/// constructs the request payload for the `/members` route
51#[derive(Debug, Clone)]
52pub enum Members {
53    /// target a specific member at `/members/{id}`
54    Identifier(String),
55    /// target all members that match the query at `/members?query...`
56    Query(MembersQuery),
57    /// target a `Work` for a specific funder at `/members/{id}/works?query..`
58    Works(WorksIdentQuery),
59}
60
61impl CrossrefRoute for Members {
62    fn route(&self) -> Result<String> {
63        match self {
64            Members::Identifier(s) => Ok(format!("{}/{}", Component::Members.route()?, s)),
65            Members::Query(query) => {
66                let query = query.route()?;
67                if query.is_empty() {
68                    Component::Members.route()
69                } else {
70                    Ok(format!("{}?{}", Component::Members.route()?, query))
71                }
72            }
73            Members::Works(combined) => Self::combined_route(combined),
74        }
75    }
76}
77
78impl CrossrefQuery for Members {
79    fn resource_component(self) -> ResourceComponent {
80        ResourceComponent::Members(self)
81    }
82}