fix(financials): emit statement line items in stable order

StatementSection.values was a HashMap, so `stocks financials -o json`
printed line items in a different order on every run. Table output
already sorted them alphabetically; JSON now matches via BTreeMap.
Values are unchanged, and older cache entries deserialize as before.

Found while capturing golden output, which needs deterministic bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
hermes 2026-10-14 08:32:27 +00:00
commit 29796f0f9d
3 changed files with 6 additions and 6 deletions

View file

@ -727,7 +727,7 @@ fn parse_statement_section(section: &RawStatementSection) -> StatementSection {
"underlyingInstrument", "underlyingInstrument",
"id", "id",
]; ];
let mut values = std::collections::HashMap::new(); let mut values = std::collections::BTreeMap::new();
for (k, v) in &section.data { for (k, v) in &section.data {
if skip_keys.contains(&k.as_str()) { if skip_keys.contains(&k.as_str()) {

View file

@ -144,7 +144,7 @@ pub struct InstrumentInfo {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StatementSection { pub struct StatementSection {
pub values: std::collections::HashMap<String, f64>, pub values: std::collections::BTreeMap<String, f64>,
pub currency: String, pub currency: String,
pub report_date: String, pub report_date: String,
pub end_date: String, pub end_date: String,

View file

@ -1006,7 +1006,7 @@ fn sort_screener_quotes(quotes: &mut [Quote], filter: &str) {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::collections::HashMap; use std::collections::BTreeMap;
use chrono::{Days, NaiveDate}; use chrono::{Days, NaiveDate};
@ -1217,19 +1217,19 @@ mod tests {
name: "BCA".into(), name: "BCA".into(),
}, },
balance_sheet: Some(StatementSection { balance_sheet: Some(StatementSection {
values: HashMap::from([("assets".into(), 1.0)]), values: BTreeMap::from([("assets".into(), 1.0)]),
currency: "IDR".into(), currency: "IDR".into(),
report_date: "2026-01-01".into(), report_date: "2026-01-01".into(),
end_date: "2025-12-31".into(), end_date: "2025-12-31".into(),
}), }),
cash_flow: Some(StatementSection { cash_flow: Some(StatementSection {
values: HashMap::from([("cash".into(), 2.0)]), values: BTreeMap::from([("cash".into(), 2.0)]),
currency: "IDR".into(), currency: "IDR".into(),
report_date: "2026-01-01".into(), report_date: "2026-01-01".into(),
end_date: "2025-12-31".into(), end_date: "2025-12-31".into(),
}), }),
income_statement: Some(StatementSection { income_statement: Some(StatementSection {
values: HashMap::from([("income".into(), 3.0)]), values: BTreeMap::from([("income".into(), 3.0)]),
currency: "IDR".into(), currency: "IDR".into(),
report_date: "2026-01-01".into(), report_date: "2026-01-01".into(),
end_date: "2025-12-31".into(), end_date: "2025-12-31".into(),