use crate::card::Card;
use crate::client::TrelloClient;
use crate::formatting::header;
use crate::trello_error::TrelloError;
use crate::trello_object::{Renderable, TrelloObject};
use colored::*;
use regex::RegexBuilder;
use serde::Deserialize;
type Result<T> = std::result::Result<T, TrelloError>;
#[derive(Deserialize, Debug, Eq, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct List {
pub id: String,
pub name: String,
pub closed: bool,
pub cards: Option<Vec<Card>>,
}
impl TrelloObject for List {
fn get_type() -> String {
String::from("List")
}
fn get_name(&self) -> &str {
&self.name
}
fn get_fields() -> &'static [&'static str] {
&["id", "name", "closed"]
}
}
impl Renderable for List {
fn render(&self, headers: bool) -> String {
let title = header(&self.name, "-").bold().to_string();
let mut result: Vec<String> = match headers {
true => vec![title],
false => vec![],
};
if let Some(cards) = &self.cards {
for c in cards {
result.push(format!("* {}", c.simple_render()));
}
}
result.join("\n")
}
fn simple_render(&self) -> String {
self.name.clone()
}
}
impl List {
pub fn new(id: &str, name: &str, cards: Option<Vec<Card>>) -> List {
List {
id: String::from(id),
name: String::from(name),
cards,
closed: false,
}
}
pub fn filter(&self, label_filter: &str) -> List {
let re = RegexBuilder::new(label_filter)
.case_insensitive(true)
.build()
.expect("Invalid regex for label filter");
let closure = |c: &Card| -> bool {
if let Some(labels) = &c.labels {
for label in labels {
if re.is_match(&label.name) {
return true;
}
}
}
false
};
let mut result = self.clone();
result.cards = result
.cards
.map(|cards| cards.into_iter().filter(closure).collect());
result
}
pub fn create(client: &TrelloClient, board_id: &str, name: &str) -> Result<List> {
let url = client.config.get_trello_url("/1/lists/", &[])?;
let params = [("name", name), ("idBoard", board_id)];
Ok(client
.client
.post(url)
.form(¶ms)
.send()?
.error_for_status()?
.json()?)
}
pub fn open(client: &TrelloClient, list_id: &str) -> Result<List> {
let url = client
.config
.get_trello_url(&format!("/1/lists/{}", &list_id), &[])?;
let params = [("closed", "false")];
Ok(client
.client
.put(url)
.form(¶ms)
.send()?
.error_for_status()?
.json()?)
}
pub fn update(client: &TrelloClient, list: &List) -> Result<List> {
let url = client
.config
.get_trello_url(&format!("/1/lists/{}/", &list.id), &[])?;
let params = [("name", &list.name), ("closed", &list.closed.to_string())];
Ok(client
.client
.put(url)
.form(¶ms)
.send()?
.error_for_status()?
.json()?)
}
pub fn get_all(client: &TrelloClient, board_id: &str, cards: bool) -> Result<Vec<List>> {
let fields = List::get_fields().join(",");
let mut params = vec![("fields", fields.as_str())];
if cards {
params.push(("cards", "open"));
}
let url = client
.config
.get_trello_url(&format!("/1/boards/{}/lists", board_id), ¶ms)?;
Ok(client.client.get(url).send()?.error_for_status()?.json()?)
}
}