stynx-code 3.2.1

stynx-code — interactive AI coding assistant
use stynx_code_provider::AnthropicProvider;

use super::terminal::{BOLD, CYAN, DIM, GREEN, RED, RESET, YELLOW};

pub(super) async fn render_usage(provider: &AnthropicProvider) -> String {
    if !provider.is_oauth() {
        return format!("\n  {DIM}/usage is only available for Claude AI subscribers (OAuth login){RESET}\n");
    }
    let utilization = match provider.fetch_usage().await {
        Ok(u) => u,
        Err(e) => return format!("\n  {BOLD}Error:{RESET} {e}\n"),
    };
    let mut out = format!("\n  {BOLD}{CYAN}Plan Usage{RESET}\n\n");
    if let Some(ref l) = utilization.five_hour { render_limit(&mut out, "Session limit (5 hours)", l); }
    if let Some(ref l) = utilization.seven_day { render_limit(&mut out, "Weekly limit (7 days)", l); }
    if let Some(ref l) = utilization.seven_day_opus { render_limit(&mut out, "Opus limit (7 days)", l); }
    if let Some(ref l) = utilization.seven_day_sonnet { render_limit(&mut out, "Sonnet limit (7 days)", l); }
    if let Some(ref extra) = utilization.extra_usage && extra.is_enabled {
        out.push_str(&format!("  {BOLD}Extra usage{RESET}\n"));
        if let (Some(used), Some(limit)) = (extra.used_credits, extra.monthly_limit) {
            out.push_str(&format!("  {DIM}Credits:{RESET} {CYAN}${used:.2}{RESET} / ${limit:.2}\n"));
        }
        if let Some(pct) = extra.utilization {
            out.push_str(&format!("  {DIM}Utilization:{RESET} {CYAN}{pct:.0}%{RESET}\n"));
        }
        out.push('\n');
    }
    if utilization.five_hour.is_none() && utilization.seven_day.is_none()
        && utilization.seven_day_opus.is_none() && utilization.seven_day_sonnet.is_none()
    {
        out.push_str(&format!("  {DIM}No usage data available.{RESET}\n"));
    }
    out
}

fn render_limit(out: &mut String, title: &str, limit: &stynx_code_provider::RateLimit) {
    let pct = limit.utilization.unwrap_or(0.0);
    let filled = (pct / 100.0 * 30.0).round() as usize;
    let empty = 30usize.saturating_sub(filled);
    let bar_color = if pct >= 90.0 { RED } else if pct >= 70.0 { YELLOW } else { GREEN };
    let bar = format!("{bar_color}{}{DIM}{}{RESET}", "".repeat(filled), "".repeat(empty));
    out.push_str(&format!("  {BOLD}{title}{RESET}\n"));
    out.push_str(&format!("  {bar}  {CYAN}{pct:.0}%{RESET} used\n"));
    if let Some(ref resets) = limit.resets_at {
        out.push_str(&format!("  {DIM}Resets {resets}{RESET}\n"));
    }
    out.push('\n');
}