trello/
board.rs

1use crate::client::TrelloClient;
2use crate::formatting::title;
3use crate::list::List;
4use crate::trello_error::TrelloError;
5use crate::trello_object::{Renderable, TrelloObject};
6
7use colored::*;
8use serde::Deserialize;
9
10type Result<T> = std::result::Result<T, TrelloError>;
11
12// https://developer.atlassian.com/cloud/trello/guides/rest-api/object-definitions/#board-object
13#[derive(Deserialize, Debug, Eq, PartialEq, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct Board {
16    pub id: String,
17    pub name: String,
18    pub closed: bool,
19    pub url: String,
20    pub lists: Option<Vec<List>>,
21}
22
23impl TrelloObject for Board {
24    fn get_type() -> String {
25        String::from("Board")
26    }
27
28    fn get_name(&self) -> &str {
29        &self.name
30    }
31
32    fn get_fields() -> &'static [&'static str] {
33        &["id", "name", "closed", "url"]
34    }
35}
36
37impl Renderable for Board {
38    fn render(&self, headers: bool) -> String {
39        let mut result = match headers {
40            true => vec![title(&self.name).bold().to_string()],
41            false => vec![],
42        };
43        if let Some(lists) = &self.lists {
44            for list in lists {
45                result.push(String::from(""));
46                result.push(list.render(true));
47            }
48        }
49        result.join("\n")
50    }
51
52    fn simple_render(&self) -> String {
53        self.name.clone()
54    }
55}
56
57impl Board {
58    pub fn new(id: &str, name: &str, lists: Option<Vec<List>>, url: &str) -> Board {
59        Board {
60            id: String::from(id),
61            name: String::from(name),
62            url: String::from(url),
63            lists,
64            closed: false,
65        }
66    }
67
68    pub fn filter(&self, filter_name: &str) -> Board {
69        let mut result = self.clone();
70
71        result.lists = if let Some(lists) = result.lists {
72            Some(lists.into_iter().map(|l| l.filter(filter_name)).collect())
73        } else {
74            None
75        };
76        result
77    }
78
79    /// Retrieves any missing nested content for the given board. This potentially
80    /// means one or more network requests in order to retrieve the data. The Board
81    /// will be mutated to include all its associated lists. The lists will also in turn
82    /// contain the associated card resources.
83    pub fn retrieve_nested(&mut self, client: &TrelloClient) -> Result<()> {
84        if self.lists.is_none() {
85            debug!("Retrieving nested data for board: {}", self.id);
86            self.lists = Some(List::get_all(client, &self.id, true)?);
87        } else {
88            debug!("No need to retrieve nested data");
89        }
90        Ok(())
91    }
92
93    pub fn create(client: &TrelloClient, name: &str) -> Result<Board> {
94        let url = client.config.get_trello_url("/1/boards/", &[])?;
95
96        let params = [("name", name)];
97
98        Ok(client
99            .client
100            .post(url)
101            .form(&params)
102            .send()?
103            .error_for_status()?
104            .json()?)
105    }
106
107    pub fn open(client: &TrelloClient, board_id: &str) -> Result<Board> {
108        let url = client
109            .config
110            .get_trello_url(&format!("/1/boards/{}", &board_id), &[])?;
111
112        let params = [("closed", "false")];
113
114        Ok(client
115            .client
116            .put(url)
117            .form(&params)
118            .send()?
119            .error_for_status()?
120            .json()?)
121    }
122
123    pub fn update(client: &TrelloClient, board: &Board) -> Result<Board> {
124        let url = client
125            .config
126            .get_trello_url(&format!("/1/boards/{}/", &board.id), &[])?;
127
128        let params = [("name", &board.name), ("closed", &board.closed.to_string())];
129
130        Ok(client
131            .client
132            .put(url)
133            .form(&params)
134            .send()?
135            .error_for_status()?
136            .json()?)
137    }
138
139    pub fn get_all(client: &TrelloClient) -> Result<Vec<Board>> {
140        let url = client.config.get_trello_url(
141            "/1/members/me/boards/",
142            &[
143                ("filter", "open"),
144                ("fields", &Board::get_fields().join(",")),
145            ],
146        )?;
147
148        Ok(client.client.get(url).send()?.error_for_status()?.json()?)
149    }
150
151    pub fn get(client: &TrelloClient, board_id: &str) -> Result<Board> {
152        let url = client.config.get_trello_url(
153            &format!("/1/boards/{}", board_id),
154            &[("fields", &Board::get_fields().join(","))],
155        )?;
156
157        Ok(client.client.get(url).send()?.error_for_status()?.json()?)
158    }
159}