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
use crate::utils::BytesWriter;
use http::{uri::Uri, HeaderMap, Method};
use std::io::Write;
#[derive(Debug, Clone)]
pub struct PixivRequest {
pub method: Method,
pub url: Uri,
pub headers: HeaderMap,
pub params: std::collections::HashMap<&'static str, String>,
pub form: std::collections::HashMap<&'static str, String>,
}
impl PixivRequest {
pub fn new(method: Method, url: Uri) -> PixivRequest {
let result = PixivRequest {
method,
url: url,
headers: HeaderMap::new(),
params: std::collections::HashMap::new(),
form: std::collections::HashMap::new(),
};
result.add_header(
http::header::REFERER,
http::header::HeaderValue::from_static("http://spapi.pixiv.net/"),
)
}
pub fn add_header<T, U>(mut self, key: T, val: U) -> Self
where
T: Into<http::header::HeaderName>,
U: Into<http::header::HeaderValue>,
{
self.headers.insert(key.into(), val.into());
self
}
pub fn add_header_str<'a, T>(mut self, key: T, val: &'a str) -> Self
where
T: Into<http::header::HeaderName>,
{
self.headers.insert(
key.into(),
http::header::HeaderValue::from_str(val).unwrap(),
);
self
}
pub fn add_param<U>(mut self, key: &'static str, val: U) -> Self
where
U: Into<String>,
{
self.params.insert(key, val.into());
self
}
pub fn maybe_add_param<U>(mut self, key: &'static str, val: Option<U>) -> Self
where
U: Into<String>,
{
if let Some(val) = val {
self.params.insert(key, val.into());
}
self
}
pub fn add_param_from_str(mut self, key: &'static str, val: &'static str) -> Self {
self.params.insert(key, String::from(val));
self
}
pub fn add_form<T>(mut self, key: &'static str, val: T) -> Self
where
T: Into<String>,
{
self.form.insert(key, val.into());
self
}
pub fn add_form_from_str(mut self, key: &'static str, val: &'static str) -> Self {
self.form.insert(key, String::from(val));
self
}
pub fn finish(mut self) -> Self {
let mut uri_parts = self.url.into_parts();
let path = uri_parts.path_and_query;
let mut buffer = BytesWriter::with_smol_capacity();
let query = serde_urlencoded::to_string(&self.params).expect("To url-encode");
let _ = match path {
Some(path) => write!(buffer, "{}?{}", path.path(), query),
None => write!(buffer, "?{}", query),
};
uri_parts.path_and_query = Some(
http::uri::PathAndQuery::from_shared(buffer.into_inner().freeze())
.expect("To create path and query"),
);
self.url = match http::Uri::from_parts(uri_parts) {
Ok(uri) => uri,
Err(error) => panic!("Unable to set query for URI: {}", error),
};
self
}
}