11use std:: { borrow:: Cow , collections:: HashMap } ;
22
33use async_trait:: async_trait;
4- use http:: { Method , HeaderMap , HeaderValue , header:: { ORIGIN , REFERER , COOKIE } } ;
4+ use http:: {
5+ header:: { COOKIE , ORIGIN , REFERER } ,
6+ HeaderMap , HeaderValue , Method ,
7+ } ;
58use log:: debug;
69use reqwest:: Url ;
710use unm_engine:: interface:: Engine ;
11+ use unm_request:: {
12+ json:: { Json , UnableToExtractJson } ,
13+ request,
14+ } ;
815use unm_selector:: SimilarSongSelector ;
9- use unm_types:: { Context , RetrievedSongInfo , SerializedIdentifier , Song , SongSearchInformation , Album } ;
10- use unm_request:: { json:: { Json , UnableToExtractJson } , request} ;
16+ use unm_types:: {
17+ Album , Context , RetrievedSongInfo , SerializedIdentifier , Song , SongSearchInformation ,
18+ } ;
1119
12- pub const ENGINE_ID : & str = "qq" ;
20+ pub const ENGINE_ID : & str = "qq" ;
1321
1422pub struct QQEngine ;
1523
@@ -19,7 +27,7 @@ impl Engine for QQEngine {
1927 & self ,
2028 info : & ' a Song ,
2129 ctx : & ' a Context ,
22- ) -> anyhow:: Result < Option < SongSearchInformation < ' static > > > {
30+ ) -> anyhow:: Result < Option < SongSearchInformation > > {
2331 log:: info!( "Searching with QQ engine" ) ;
2432
2533 let response = get_search_data ( & info. keyword ( ) , ctx) . await ?;
@@ -35,25 +43,25 @@ impl Engine for QQEngine {
3543 let matched = find_match ( info, result) . await ?;
3644
3745 if let Some ( song) = matched {
38- Ok ( Some ( SongSearchInformation {
39- source : Cow :: Borrowed ( ENGINE_ID ) ,
40- identifier : song. id . to_string ( ) ,
41- song : Some ( song) ,
42- } ) )
46+ Ok ( Some (
47+ SongSearchInformation :: builder ( )
48+ . source ( ENGINE_ID . into ( ) )
49+ . identifier ( song. id . to_string ( ) )
50+ . song ( Some ( song) )
51+ . build ( )
52+ ) )
4353 } else {
4454 Ok ( None )
4555 }
4656 }
4757
48-
4958 async fn retrieve < ' a > (
5059 & self ,
51- identifier : & ' a SerializedIdentifier ,
52- ctx : & ' a Context ,
53- ) -> anyhow:: Result < RetrievedSongInfo < ' static > > {
60+ _identifier : & ' a SerializedIdentifier ,
61+ _ctx : & ' a Context ,
62+ ) -> anyhow:: Result < RetrievedSongInfo > {
5463 todo ! ( )
5564 }
56-
5765}
5866
5967async fn get_search_data ( keyword : & str , ctx : & Context ) -> anyhow:: Result < Json > {
@@ -66,7 +74,7 @@ async fn get_search_data(keyword: &str, ctx: &Context) -> anyhow::Result<Json> {
6674 & url,
6775 Some ( construct_header ( cookie) ?) ,
6876 None ,
69- ctx. try_get_proxy ( ) ?
77+ ctx. try_get_proxy ( ) ?,
7078 )
7179 . await ?;
7280 Ok ( res. json ( ) . await ?)
@@ -123,23 +131,28 @@ fn format(song: &Json) -> anyhow::Result<Song> {
123131 json_pointer : "/songmid" ,
124132 expected_type : "string" ,
125133 } ) ?;
126- let mut context = HashMap :: new ( ) ;
127- context. insert ( "media_mid" . to_string ( ) , media_mid. to_string ( ) ) ;
128- context. insert ( "songmid" . to_string ( ) , song_mid. to_string ( ) ) ;
129-
130- let x = Song {
131- id : id. to_string ( ) ,
132- name : String :: from ( name) ,
133- duration : Some ( duration * 1000 ) ,
134- artists : vec ! [ ] ,
135- album : Some ( Album {
136- id : album_id. to_string ( ) ,
137- name : String :: from ( album_name) ,
138- } ) ,
139- context : Some ( context) ,
134+ let context = {
135+ let mut context = HashMap :: new ( ) ;
136+ context. insert ( "media_mid" . to_string ( ) , media_mid. to_string ( ) ) ;
137+ context. insert ( "songmid" . to_string ( ) , song_mid. to_string ( ) ) ;
138+
139+ context
140140 } ;
141141
142- Ok ( x)
142+ Ok (
143+ Song :: builder ( )
144+ . id ( id. to_string ( ) )
145+ . name ( name. to_string ( ) )
146+ . duration ( Some ( duration * 1000 ) )
147+ . album ( Some (
148+ Album :: builder ( )
149+ . id ( album_id. to_string ( ) )
150+ . name ( album_name. to_string ( ) )
151+ . build ( )
152+ ) )
153+ . context ( Some ( context) )
154+ . build ( )
155+ )
143156}
144157
145158fn construct_header ( cookie : Option < & str > ) -> anyhow:: Result < HeaderMap > {
@@ -159,7 +172,7 @@ fn construct_header(cookie: Option<&str>) -> anyhow::Result<HeaderMap> {
159172
160173fn construct_search_url ( keyword : & str ) -> anyhow:: Result < Url > {
161174 Ok ( Url :: parse_with_params (
162- "https://c.y.qq.com/soso/fcgi-bin/client_search_cp?" ,
175+ "https://c.y.qq.com/soso/fcgi-bin/client_search_cp?" ,
163176 & [
164177 ( "ct" , "24" ) ,
165178 ( "qqmusic_ver" , "1298" ) ,
@@ -181,28 +194,28 @@ fn construct_search_url(keyword: &str) -> anyhow::Result<Url> {
181194 ( "outCharset" , "utf-8" ) ,
182195 ( "notice" , "0" ) ,
183196 ( "platform" , "yqq" ) ,
184- ( "needNewCode" , "0" )
185- ]
197+ ( "needNewCode" , "0" ) ,
198+ ] ,
186199 ) ?)
187200}
188201
189202#[ cfg( test) ]
190203mod tests {
191204 use tokio:: test;
192- use unm_types:: { Context , Artist } ;
205+ use unm_types:: { Artist , Context } ;
193206
194207 use super :: * ;
195208
196209 fn get_info_1 ( ) -> Song {
197210 // https://music.163.com/api/song/detail?ids=[385552]
198- Song {
199- name : String :: from ( "干杯" ) ,
200- artists : vec ! [ Artist {
201- name : String :: from ( "五月天" ) ,
202- .. Default :: default ( )
203- } ] ,
204- .. Default :: default ( )
205- }
211+ Song :: builder ( )
212+ . name ( "干杯" . to_string ( ) )
213+ . artists ( vec ! [
214+ Artist :: builder ( )
215+ . name ( "五月天" . to_string ( ) )
216+ . build ( )
217+ ] )
218+ . build ( )
206219 }
207220
208221 #[ test]
0 commit comments