1use colored::Colorize;
2use thiserror::Error;
3
4use crate::{cli::Sorting, palette::Palettes};
5
6#[derive(Debug, Error)]
7pub enum Error {
8 #[error(transparent)]
9 RequestError(#[from] reqwest::Error),
10
11 #[error(transparent)]
12 DeserializationError(#[from] serde_json::Error),
13}
14
15#[derive(Clone)]
17pub enum Filter {
18 Any,
20 Max(u16),
22 Min(u16),
24 Exact(u16),
26}
27
28pub struct Search {
29 pub page: u16,
31 pub filter: Filter,
33 pub sorting: Sorting,
35 pub tag: String,
37}
38
39impl Search {
40 pub fn new(page: Option<u16>, filter: Filter, sorting: Sorting, tag: Option<String>) -> Self {
41 Self {
42 page: page.unwrap_or(1),
43 filter,
44 sorting,
45 tag: tag.unwrap_or("".to_string()),
46 }
47 }
48
49 fn to_query(self) -> Vec<(&'static str, String)> {
51 let mut params = vec![
52 ("page", format!("{}", self.page)),
53 ("sortingType", self.sorting.to_string()),
54 ("tag", self.tag),
55 ];
56
57 match self.filter {
58 Filter::Any => params.push(("colorNumberFilterType", "any".to_string())),
59 Filter::Max(n) => {
60 params.push(("colorNumberFilterType", "max".to_string()));
61 params.push(("colorNumber", format!("{}", n)));
62 }
63 Filter::Min(n) => {
64 params.push(("colorNumberFilterType", "min".to_string()));
65 params.push(("colorNumber", format!("{}", n)));
66 }
67 Filter::Exact(n) => {
68 params.push(("colorNumberFilterType", "exact".to_string()));
69 params.push(("colorNumber", format!("{}", n)));
70 }
71 }
72
73 params
74 }
75
76 pub async fn execute(self) -> Result<(), Error> {
78 let client = reqwest::Client::new();
79
80 let response = client
81 .get("https://lospec.com/palette-list/load")
82 .query(&self.to_query())
83 .send()
84 .await?;
85
86 let json: Palettes =
87 serde_json::from_slice(&response.bytes().await.map_err(Error::RequestError)?)?;
88
89 for palette in &json.palettes {
90 if let Some(user) = &palette.user {
91 println!("{} ({}) by {}", palette.title, palette.slug, user.name);
92 } else {
93 println!("{}", palette.title);
94 }
95
96 for color in &palette.colors {
97 let colored_string = " ".on_truecolor(color.red, color.green, color.blue);
98 print!("{}", colored_string);
99 }
100 println!();
101 println!();
102 }
103
104 Ok(())
105 }
106}