1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::{
client::{AuthorizedClient, GeneralErrHandler, ID},
errors::{Error, ErrorKind, Result},
};
use chrono::{DateTime, FixedOffset};
use failure::Fail;
use log::debug;
use reqwest::{blocking::Response, StatusCode};
use serde::{self, Deserialize, Serialize};
use std::string::ToString;
#[derive(Serialize, Debug)]
pub struct CollectionsQuery<'a> {
include_public: bool,
name: Option<&'a str>,
ids: Option<Vec<&'a str>>,
}
impl<'a> Default for CollectionsQuery<'a> {
fn default() -> Self {
CollectionsQuery {
include_public: false,
name: None,
ids: None,
}
}
}
impl<'a> CollectionsQuery<'a> {
pub fn new() -> Self { Default::default() }
pub fn include_public(self) -> CollectionsQuery<'a> {
CollectionsQuery {
include_public: true,
..self
}
}
pub fn name(self, name: &'a str) -> CollectionsQuery<'a> {
CollectionsQuery {
name: Some(name),
..self
}
}
pub fn ids(self, ids: Vec<&'a str>) -> CollectionsQuery<'a> { CollectionsQuery { ids: Some(ids), ..self } }
}
#[derive(Deserialize, Serialize, Debug)]
pub struct CollectionsResult {
pub collections: Vec<Collection>,
}
impl Default for CollectionsResult {
fn default() -> CollectionsResult {
CollectionsResult {
collections: Vec::with_capacity(0),
}
}
}
#[derive(Deserialize, Serialize, Debug)]
pub struct Collection {
pub id: String,
pub public: bool,
pub name: String,
pub owner: ID,
pub auditing: bool,
#[serde(rename = "archived-date")]
pub archived_date: Option<DateTime<FixedOffset>>,
#[serde(rename = "has-folders")]
pub has_folders: Option<bool>,
}
pub fn search_collections(
authorized_client: &AuthorizedClient,
collection_query: CollectionsQuery,
) -> Result<CollectionsResult> {
let url = format!("https://api.{}/v2/collections", authorized_client.base_url);
let ids_str;
let mut params = Vec::new();
if collection_query.include_public {
params.push(("include-public", "true"));
}
if let Some(name) = collection_query.name {
params.push(("name", name));
}
if let Some(ids) = collection_query.ids {
ids_str = ids.as_slice().join(",");
params.push(("ids", &ids_str));
}
let request = authorized_client
.http_client
.get(&url)
.query(¶ms)
.bearer_auth(&authorized_client.token.access_token);
debug!("Request: '{:#?}'", request);
let response: Response = request
.send()
.map_err(|e| e.context(ErrorKind::HttpRequestFailed))?
.general_err_handler(&[StatusCode::OK, StatusCode::NO_CONTENT])?;
debug!("Response: '{:#?}'", response);
let result = match response.status() {
status @ StatusCode::OK => {
response.json().map_err(|e| {
e.context(ErrorKind::FailedToProcessHttpResponse(
status,
"reading body".to_string(),
))
})?
}
StatusCode::NO_CONTENT => CollectionsResult::default(),
code => {
return Err(Error::from(ErrorKind::ApiCallFailed(
code,
"unexpected response code".to_string(),
)))
}
};
Ok(result)
}