1use std::borrow::Cow;
2
3use super::StreamingLinkList;
4use crate::file::FileIdentifier;
5
6#[derive(Debug, Default, serde::Serialize)]
8pub struct GetFileLinkParams<'a> {
9 #[serde(
11 rename = "forcedownload",
12 skip_serializing_if = "crate::request::is_false",
13 serialize_with = "crate::request::serialize_bool"
14 )]
15 force_download: bool,
16
17 #[serde(rename = "contenttype", skip_serializing_if = "Option::is_none")]
19 content_type: Option<Cow<'a, str>>,
20
21 #[serde(rename = "maxspeed", skip_serializing_if = "Option::is_none")]
23 max_speed: Option<u64>,
24
25 #[serde(
27 rename = "skip_filename",
28 skip_serializing_if = "crate::request::is_false",
29 serialize_with = "crate::request::serialize_bool"
30 )]
31 skip_filename: bool,
32}
33
34impl<'a> GetFileLinkParams<'a> {
35 pub fn set_force_download(&mut self, value: bool) {
41 self.force_download = value;
42 }
43
44 pub fn with_force_download(mut self, value: bool) -> Self {
50 self.set_force_download(value);
51 self
52 }
53
54 pub fn set_content_type(&mut self, value: impl Into<Cow<'a, str>>) {
60 self.content_type = Some(value.into());
61 }
62
63 pub fn with_content_type(mut self, value: impl Into<Cow<'a, str>>) -> Self {
69 self.set_content_type(value);
70 self
71 }
72
73 pub fn set_max_speed(&mut self, value: u64) {
79 self.max_speed = Some(value);
80 }
81
82 pub fn with_max_speed(mut self, value: u64) -> Self {
88 self.set_max_speed(value);
89 self
90 }
91
92 pub fn set_skip_filename(&mut self, value: bool) {
98 self.skip_filename = value;
99 }
100
101 pub fn with_skip_filename(mut self, value: bool) -> Self {
107 self.set_skip_filename(value);
108 self
109 }
110}
111
112#[derive(serde::Serialize)]
114struct Params<'a> {
115 #[serde(flatten)]
117 identifier: FileIdentifier<'a>,
118
119 #[serde(flatten)]
121 params: GetFileLinkParams<'a>,
122}
123
124impl crate::Client {
125 pub async fn get_file_link(
135 &self,
136 identifier: impl Into<FileIdentifier<'_>>,
137 ) -> crate::Result<StreamingLinkList> {
138 self.get_request::<StreamingLinkList, _>("getfilelink", identifier.into())
139 .await
140 }
141
142 pub async fn get_file_link_with_params(
153 &self,
154 identifier: impl Into<FileIdentifier<'_>>,
155 params: GetFileLinkParams<'_>,
156 ) -> crate::Result<StreamingLinkList> {
157 self.get_request::<StreamingLinkList, _>(
158 "getfilelink",
159 Params {
160 identifier: identifier.into(),
161 params,
162 },
163 )
164 .await
165 }
166}
167
168#[cfg(test)]
169mod tests {
170 use crate::{Client, Credentials};
171 use mockito::Matcher;
172
173 #[tokio::test]
174 async fn success() {
175 let mut server = mockito::Server::new_async().await;
176 let m = server.mock("GET", "/getfilelink")
177 .match_query(Matcher::AllOf(vec![
178 Matcher::UrlEncoded("access_token".into(), "access-token".into()),
179 Matcher::UrlEncoded("fileid".into(), "42".into()),
180 ]))
181 .with_status(200)
182 .with_body(r#"{
183 "result": 0,
184 "dwltag": "yvkNr0TqT6HFAWlVpdnHs5",
185 "hash": 17869736033964340520,
186 "size": 10485760,
187 "expires": "Sat, 24 Jul 2021 03:18:31 +0000",
188 "path": "\/DLZCAt2vXZejNfL5ZruLVZZTk2ev7Z2ZZNR5ZZdoz6ZXZQZZErw4bH0PfzBQt3LlgXMliXVtietX\/SAkdyBjkA7mQABbT.bin",
189 "hosts": [
190 "edef2.pcloud.com",
191 "eu3.pcloud.com"
192 ]
193}"#)
194.create();
195 let client = Client::new(server.url(), Credentials::access_token("access-token")).unwrap();
196 let result = client.get_file_link(42).await.unwrap();
197 let mut iter = result.links();
198 assert_eq!(iter.next().unwrap().to_string(), "https://edef2.pcloud.com/DLZCAt2vXZejNfL5ZruLVZZTk2ev7Z2ZZNR5ZZdoz6ZXZQZZErw4bH0PfzBQt3LlgXMliXVtietX/SAkdyBjkA7mQABbT.bin");
199 m.assert();
200 }
201}