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
use crate::client::TrelloClient;
use crate::formatting::header;
use crate::trello_error::TrelloError;
use crate::trello_object::{Renderable, TrelloObject};

use serde::Deserialize;

type Result<T> = std::result::Result<T, TrelloError>;

#[derive(Deserialize, Debug, Eq, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Attachment {
    pub id: String,
    pub name: String,
    pub url: String,
}

impl Attachment {
    pub fn get_all(client: &TrelloClient, card_id: &str) -> Result<Vec<Attachment>> {
        let url = client.config.get_trello_url(
            &format!("/1/cards/{}/attachments", card_id),
            &[("fields", &Attachment::get_fields().join(","))],
        )?;

        Ok(client.client.get(url).send()?.error_for_status()?.json()?)
    }

    pub fn apply(client: &TrelloClient, card_id: &str, file: &str) -> Result<Attachment> {
        let url = client
            .config
            .get_trello_url(&format!("/1/cards/{}/attachments", card_id), &[])?;

        let form = reqwest::blocking::multipart::Form::new().file("file", file)?;

        Ok(client
            .client
            .post(url)
            .multipart(form)
            .send()?
            .error_for_status()?
            .json()?)
    }
}

impl TrelloObject for Attachment {
    fn get_type() -> String {
        String::from("Attachment")
    }

    fn get_name(&self) -> &str {
        &self.name
    }

    fn get_fields() -> &'static [&'static str] {
        &["id", "name", "url"]
    }
}

impl Renderable for Attachment {
    fn render(&self) -> String {
        [header(&self.name, "-").as_str(), &self.url].join("\n")
    }

    fn simple_render(&self) -> String {
        self.name.clone()
    }
}