Skip to main content

schwab_cli/human/
mod.rs

1use anyhow::{Context, Result};
2use inquire::Select;
3
4use crate::config::RuntimeConfig;
5
6pub async fn pick_account_hash(_runtime: &RuntimeConfig, api: &schwab_api::TraderApi) -> Result<String> {
7    let numbers = api
8        .accounts()
9        .account_numbers()
10        .await
11        .context("Failed to list account numbers")?;
12
13    if numbers.is_empty() {
14        anyhow::bail!("No linked accounts found");
15    }
16
17    let labels: Vec<String> = numbers
18        .iter()
19        .map(|n| format!("{}  (hash: {}…)", n.account_number, &n.hash_value[..n.hash_value.len().min(8)]))
20        .collect();
21
22    let choice = Select::new("Select account", labels.clone()).prompt()?;
23    let idx = labels
24        .iter()
25        .position(|l| l == &choice)
26        .context("Invalid selection")?;
27
28    Ok(numbers[idx].hash_value.clone())
29}
30
31pub fn read_order_json(prompt: &str) -> Result<serde_json::Value> {
32    let raw = inquire::Text::new(prompt)
33        .with_help_message("Path to .json file or inline JSON object")
34        .prompt()?;
35    parse_order_input(&raw)
36}
37
38pub fn parse_order_input(raw: &str) -> Result<serde_json::Value> {
39    let path = std::path::Path::new(raw.trim());
40    if path.is_file() {
41        let content = std::fs::read_to_string(path)?;
42        Ok(serde_json::from_str(&content)?)
43    } else {
44        Ok(serde_json::from_str(raw)?)
45    }
46}