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
68
69
70
use super::board::Board;
use super::card::Card;
use super::client::TrelloClient;
use super::trello_error::TrelloError;
use super::trello_object::TrelloObject;

use serde::Deserialize;

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

pub struct SearchOptions {
    pub partial: bool,
    pub cards_limit: Option<i32>,
    pub boards_limit: Option<i32>,
}

impl Default for SearchOptions {
    fn default() -> Self {
        SearchOptions {
            partial: false,
            cards_limit: None,
            boards_limit: None,
        }
    }
}

#[derive(Deserialize, Debug, Eq, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SearchResult {
    #[serde(default = "Vec::new")]
    pub cards: Vec<Card>,
    #[serde(default = "Vec::new")]
    pub boards: Vec<Board>,
}

/// Implements the Trello Search API
/// https://developer.atlassian.com/cloud/trello/rest/api-group-search/#api-search-get
pub fn search(
    client: &TrelloClient,
    search_term: &str,
    options: &SearchOptions,
) -> Result<SearchResult> {
    let partial = options.partial.to_string();
    let card_fields = Card::get_fields().join(",");
    let board_fields = Board::get_fields().join(",");

    let mut params = vec![
        ("query", search_term),
        ("partial", &partial),
        ("card_fields", &card_fields),
        ("board_fields", &board_fields),
    ];

    // declared in the outer scope so that references live long enough
    let cards_limit;
    let boards_limit;

    if let Some(value) = options.cards_limit {
        cards_limit = value.to_string();
        params.push(("cards_limit", &cards_limit));
    }
    if let Some(value) = options.boards_limit {
        boards_limit = value.to_string();
        params.push(("boards_limit", &boards_limit));
    }

    let url = client.config.get_trello_url("/1/search/", &params)?;

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