@@ -3382,7 +3382,10 @@ fn print_financial_report_snapshot(data: &Value) {
33823382
33833383// ── macrodata ────────────────────────────────────────────────────────────────
33843384
3385- use longbridge:: fundamental:: { Macrodata , MacrodataIndicator , MacrodataResponse } ;
3385+ use longbridge:: fundamental:: {
3386+ Macrodata , MacrodataCountry , MacrodataIndicator , MacrodataIndicatorListResponse ,
3387+ MacrodataResponse ,
3388+ } ;
33863389
33873390fn ml_text ( t : & longbridge:: fundamental:: MultiLanguageText ) -> & str {
33883391 if !t. simplified_chinese . is_empty ( ) {
@@ -3394,12 +3397,13 @@ fn ml_text(t: &longbridge::fundamental::MultiLanguageText) -> &str {
33943397 }
33953398}
33963399
3397- fn print_macrodata_list ( indicators : & [ MacrodataIndicator ] ) {
3398- if indicators . is_empty ( ) {
3400+ fn print_macrodata_list ( resp : & MacrodataIndicatorListResponse ) {
3401+ if resp . data . is_empty ( ) {
33993402 println ! ( "No indicators found." ) ;
34003403 return ;
34013404 }
3402- let rows: Vec < Vec < String > > = indicators
3405+ let rows: Vec < Vec < String > > = resp
3406+ . data
34033407 . iter ( )
34043408 . map ( |i| {
34053409 let name = ml_text ( & i. name ) ;
@@ -3418,6 +3422,7 @@ fn print_macrodata_list(indicators: &[MacrodataIndicator]) {
34183422 ]
34193423 } )
34203424 . collect ( ) ;
3425+ println ! ( "Total: {}" , resp. count) ;
34213426 super :: output:: print_table (
34223427 & [ "Code" , "Name" , "Category" , "Country" , "Frequency" , "Source" ] ,
34233428 rows,
@@ -3528,9 +3533,22 @@ fn macrodata_record_to_json(r: &Macrodata) -> Value {
35283533 } )
35293534}
35303535
3536+ fn parse_country ( s : & str ) -> Option < MacrodataCountry > {
3537+ match s. to_uppercase ( ) . as_str ( ) {
3538+ "HK" => Some ( MacrodataCountry :: HongKong ) ,
3539+ "CN" => Some ( MacrodataCountry :: China ) ,
3540+ "US" => Some ( MacrodataCountry :: UnitedStates ) ,
3541+ "EU" => Some ( MacrodataCountry :: EuroZone ) ,
3542+ "JP" => Some ( MacrodataCountry :: Japan ) ,
3543+ "SG" => Some ( MacrodataCountry :: Singapore ) ,
3544+ _ => None ,
3545+ }
3546+ }
3547+
35313548/// List all macroeconomic indicators, or query historical data for one indicator.
35323549pub async fn cmd_macrodata (
35333550 code : Option < String > ,
3551+ country : Option < String > ,
35343552 start : Option < String > ,
35353553 end : Option < String > ,
35363554 limit : Option < u32 > ,
@@ -3546,39 +3564,62 @@ pub async fn cmd_macrodata(
35463564 None => {
35473565 let limit_val = limit. unwrap_or ( 1000 ) ;
35483566 let offset = ( page. saturating_sub ( 1 ) ) * limit_val;
3567+ let country_filter = country
3568+ . as_deref ( )
3569+ . map ( |c| {
3570+ parse_country ( c) . ok_or_else ( || {
3571+ anyhow:: anyhow!( "Unknown country '{c}'. Use: HK, CN, US, EU, JP, SG" )
3572+ } )
3573+ } )
3574+ . transpose ( ) ?;
35493575 if verbose {
3550- eprintln ! ( "* macrodata_indicators(offset={offset}, limit={limit_val})" ) ;
3576+ eprintln ! (
3577+ "* macrodata_indicators(country={:?}, offset={offset}, limit={limit_val})" ,
3578+ country. as_deref( ) . unwrap_or( "-" )
3579+ ) ;
35513580 }
3552- let indicators = ctx
3553- . macrodata_indicators ( Some ( offset as i32 ) , Some ( limit_val as i32 ) )
3581+ let resp = ctx
3582+ . macrodata_indicators (
3583+ country_filter,
3584+ Some ( offset. cast_signed ( ) ) ,
3585+ Some ( limit_val. cast_signed ( ) ) ,
3586+ )
35543587 . await ?;
35553588 match format {
35563589 OutputFormat :: Json => {
3557- let arr: Vec < Value > =
3558- indicators. iter ( ) . map ( macrodata_indicator_to_json) . collect ( ) ;
3559- print_json ( & Value :: Array ( arr) ) ;
3590+ let json = serde_json:: json!( {
3591+ "count" : resp. count,
3592+ "list" : resp. data. iter( ) . map( macrodata_indicator_to_json) . collect:: <Vec <_>>( ) ,
3593+ } ) ;
3594+ print_json ( & json) ;
35603595 }
3561- OutputFormat :: Pretty => print_macrodata_list ( & indicators ) ,
3596+ OutputFormat :: Pretty => print_macrodata_list ( & resp ) ,
35623597 }
35633598 }
35643599 Some ( ref indicator_code) => {
3600+ let limit_val = limit. unwrap_or ( 20 ) ;
3601+ let offset = ( page. saturating_sub ( 1 ) ) * limit_val;
35653602 if verbose {
35663603 eprintln ! (
3567- "* macrodata(code={indicator_code}, start={}, end={}, limit={})" ,
3604+ "* macrodata(code={indicator_code}, start={}, end={}, offset={offset}, limit={limit_val })" ,
35683605 start. as_deref( ) . unwrap_or( "-" ) ,
35693606 end. as_deref( ) . unwrap_or( "-" ) ,
3570- limit. unwrap_or( 20 ) ,
35713607 ) ;
35723608 }
35733609 let resp = ctx
3574- . macrodata ( indicator_code. clone ( ) , start, end, limit. map ( |l| l as i32 ) )
3610+ . macrodata (
3611+ indicator_code. clone ( ) ,
3612+ start,
3613+ end,
3614+ Some ( offset. cast_signed ( ) ) ,
3615+ Some ( limit_val. cast_signed ( ) ) ,
3616+ )
35753617 . await
35763618 . map_err ( |e| {
35773619 let msg = e. to_string ( ) ;
35783620 if msg. contains ( "null" ) || msg. contains ( "deserialize" ) {
35793621 anyhow:: anyhow!(
3580- "Indicator code '{}' not found or returned no data" ,
3581- indicator_code
3622+ "Indicator code '{indicator_code}' not found or returned no data"
35823623 )
35833624 } else {
35843625 anyhow:: Error :: from ( e)
@@ -3587,6 +3628,7 @@ pub async fn cmd_macrodata(
35873628 match format {
35883629 OutputFormat :: Json => {
35893630 let json = serde_json:: json!( {
3631+ "count" : resp. count,
35903632 "info" : macrodata_indicator_to_json( & resp. info) ,
35913633 "data" : resp. data. iter( ) . map( macrodata_record_to_json) . collect:: <Vec <_>>( ) ,
35923634 } ) ;
0 commit comments