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
use std::fmt::Write;

use crate::{GETResult, QQMusicApi};

pub trait Search {
    fn search<T: SearchType>(
        &self,
        key: &str,
        page_num: Option<u32>,
        page_size: Option<u32>,
    ) -> GETResult;
}

impl Search for QQMusicApi {
    fn search<T: SearchType>(
        &self,
        key: &str,
        page_num: Option<u32>,
        page_size: Option<u32>,
    ) -> GETResult {
        let mut url = self.base_url.clone();

        url.set_path("/search");

        let mut query = format!("key={key}&t={}", T::TYPE_ID);

        if let Some(page_num) = page_num {
            query.write_fmt(format_args!("&pageNo={page_num}")).unwrap();
        }
        if let Some(page_size) = page_size {
            query
                .write_fmt(format_args!("&pageSize={page_size}"))
                .unwrap();
        }

        url.set_query(Some(&query));

        http::Request::builder()
            .method("GET")
            .uri(url.as_str())
            .body(())
    }
}

macro_rules! search_type {
    ( $t:ident, $id:expr, $r:ident ) => {
        pub struct $t;
        impl SearchType for $t {
            const TYPE_ID: u32 = $id;
            type Resp = crate::types::search::search_type::$r;
        }
    };
}

pub trait SearchType {
    const TYPE_ID: u32;
    type Resp;
}

search_type!(Track, 0, TrackSearchResp);

// search_type!(TrackList, 2, TrackListSearchResp);
// search_type!(Track, 7, LyricSearchResp);
// search_type!(Track, 8, AlbumSearchResp);
// search_type!(Track, 9, ArtistSearchResp);
// search_type!(Track, 12, MVSearchResp);