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#[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 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(¶ms)
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(¶ms)
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(¶ms)
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}