use std::future::Future;
use marketsurge_client::Client;
use serde::Serialize;
use crate::common::auth::make_client;
use crate::output::{finish_output, print_json};
pub async fn run_client_command<T, F, Fut>(json_table: bool, execute: F) -> i32
where
T: Serialize,
F: FnOnce(Client) -> Fut,
Fut: Future<Output = Result<Vec<T>, i32>>,
{
let client = match make_client().await {
Ok(c) => c,
Err(code) => return code,
};
match execute(client).await {
Ok(records) => finish_output(print_json(&records, json_table)),
Err(code) => code,
}
}
pub async fn run_command<'a, T, F, Fut>(symbols: &'a [String], json_table: bool, execute: F) -> i32
where
T: Serialize,
F: FnOnce(Client, Vec<&'a str>) -> Fut,
Fut: Future<Output = Result<Vec<T>, i32>>,
{
let symbol_refs: Vec<&str> = symbols.iter().map(String::as_str).collect();
run_client_command(json_table, |client| execute(client, symbol_refs)).await
}
pub fn zip_symbols<'a, T>(
symbols: &'a [&str],
items: &'a [T],
) -> impl Iterator<Item = (&'a str, &'a T)> {
items
.iter()
.enumerate()
.map(move |(i, item)| (*symbols.get(i).unwrap_or(&"???"), item))
}
#[cfg(test)]
mod tests {
use super::zip_symbols;
fn collect_pairs<'a, T>(symbols: &'a [&str], items: &'a [T]) -> Vec<(&'a str, &'a T)> {
zip_symbols(symbols, items).collect()
}
#[test]
fn test_zip_symbols_equal_length() {
let symbols = ["AAPL", "MSFT"];
let items = [1, 2];
let zipped = collect_pairs(&symbols, &items);
assert_eq!(zipped, vec![("AAPL", &1), ("MSFT", &2)]);
}
#[test]
fn test_zip_symbols_more_items_than_symbols() {
let symbols = ["AAPL"];
let items = [1, 2, 3];
let zipped = collect_pairs(&symbols, &items);
assert_eq!(zipped, vec![("AAPL", &1), ("???", &2), ("???", &3)]);
}
#[test]
fn test_zip_symbols_empty_symbols_non_empty_items() {
let symbols: [&str; 0] = [];
let items = [1, 2];
let zipped = collect_pairs(&symbols, &items);
assert_eq!(zipped, vec![("???", &1), ("???", &2)]);
}
#[test]
fn test_zip_symbols_empty_items() {
let symbols = ["AAPL"];
let items: [i32; 0] = [];
let zipped = collect_pairs(&symbols, &items);
assert!(zipped.is_empty());
}
#[test]
fn test_zip_symbols_both_empty() {
let symbols: [&str; 0] = [];
let items: [i32; 0] = [];
let zipped = collect_pairs(&symbols, &items);
assert_eq!(zipped, Vec::new());
}
}