1use crate::client::TrelloClient;
2use crate::formatting::header;
3use crate::trello_error::TrelloError;
4use crate::trello_object::{Renderable, TrelloObject};
5
6use serde::Deserialize;
7
8type Result<T> = std::result::Result<T, TrelloError>;
9
10#[derive(Deserialize, Debug, Eq, PartialEq, Clone)]
11#[serde(rename_all = "camelCase")]
12pub struct Attachment {
13 pub id: String,
14 pub name: String,
15 pub url: String,
16}
17
18impl Attachment {
19 pub fn get_all(client: &TrelloClient, card_id: &str) -> Result<Vec<Attachment>> {
20 let url = client.config.get_trello_url(
21 &format!("/1/cards/{}/attachments", card_id),
22 &[("fields", &Attachment::get_fields().join(","))],
23 )?;
24
25 Ok(client.client.get(url).send()?.error_for_status()?.json()?)
26 }
27
28 pub fn apply(client: &TrelloClient, card_id: &str, file: &str) -> Result<Attachment> {
29 let url = client
30 .config
31 .get_trello_url(&format!("/1/cards/{}/attachments", card_id), &[])?;
32
33 let form = reqwest::blocking::multipart::Form::new().file("file", file)?;
34
35 Ok(client
36 .client
37 .post(url)
38 .multipart(form)
39 .send()?
40 .error_for_status()?
41 .json()?)
42 }
43}
44
45impl TrelloObject for Attachment {
46 fn get_type() -> String {
47 String::from("Attachment")
48 }
49
50 fn get_name(&self) -> &str {
51 &self.name
52 }
53
54 fn get_fields() -> &'static [&'static str] {
55 &["id", "name", "url"]
56 }
57}
58
59impl Renderable for Attachment {
60 fn render(&self, headers: bool) -> String {
61 match headers {
62 true => [header(&self.name, "-").as_str(), &self.url].join("\n"),
63 false => self.url.clone(),
64 }
65 }
66
67 fn simple_render(&self) -> String {
68 self.name.clone()
69 }
70}