cargo-port 0.2.1

A TUI for inspecting and managing Rust projects
use std::time::Duration;

// ── Shared icons ─────────────────────────────────────────────────────

pub(crate) const CI_PASSED: &str = "🟢";
pub(crate) const CI_FAILED: &str = "🔴";
pub(crate) const CI_CANCELLED: &str = "🌑";
pub(crate) const CI_SKIPPED: &str = "";
pub(crate) const IN_SYNC: &str = "☑️";
pub(crate) const NO_REMOTE_SYNC: &str = "──";
pub(crate) const SYNC_UP: &str = "";
pub(crate) const SYNC_DOWN: &str = "";

// ── Lint status icons ────────────────────────────────────────────────

pub(crate) const LINT_PASSED: &str = "🟢";
pub(crate) const LINT_FAILED: &str = "🔴";
pub(crate) const LINT_STALE: &str = "";
pub(crate) const LINT_NO_LOG: &str = " ";

// ── Git UI constants ─────────────────────────────────────────────────

pub(crate) const GIT_LOCAL: &str = "📁";
pub(crate) const GIT_CLONE: &str = "👯";
pub(crate) const GIT_FORK: &str = "🔱";
pub(crate) const WORKTREE: &str = "🌲";
pub(crate) const GIT_STATUS_CLEAN: &str = "";
pub(crate) const GIT_STATUS_UNTRACKED: &str = "🆕";
pub(crate) const GIT_STATUS_MODIFIED: &str = "🟠";

// ── CI constants ──────────────────────────────────────────────────────

pub(crate) const GH_TIMEOUT: Duration = Duration::from_secs(5);

// ── Cache constants ───────────────────────────────────────────────────

pub(crate) const CI_CACHE_DIR: &str = "ci";
pub(crate) const LINTS_CACHE_DIR: &str = "lint-runs";

// ── Cargo / git paths ─────────────────────────────────────────────────

pub(crate) const CARGO_COMMAND_NAME: &str = "cargo";
pub(crate) const CARGO_CONFIG: &str = "config";
pub(crate) const CARGO_CONFIG_TOML: &str = "config.toml";
pub(crate) const CARGO_LOCK: &str = "Cargo.lock";
pub(crate) const CARGO_TOML: &str = "Cargo.toml";
pub(crate) const DOT_CARGO_DIR: &str = ".cargo";
pub(crate) const GIT_DIR: &str = ".git";
pub(crate) const GIT_REMOTE_SUFFIX: &str = ".git";
pub(crate) const RUST_TOOLCHAIN: &str = "rust-toolchain";
pub(crate) const RUST_TOOLCHAIN_TOML: &str = "rust-toolchain.toml";
pub(crate) const TARGET_DIR: &str = "target";

// ── Scan constants ────────────────────────────────────────────────────

pub(crate) const NO_MORE_RUNS_MARKER: &str = ".no_more_runs";
pub(crate) const SCAN_DISK_CONCURRENCY: usize = 6;
/// `cargo metadata --no-deps` per workspace root, capped so a large multi-
/// workspace tree doesn't monopolize the blocking pool. Runs briefly —
/// milliseconds per invocation on typical workspaces — so a small cap is
/// enough to preserve fairness with other enrichment tasks.
pub(crate) const SCAN_METADATA_CONCURRENCY: usize = 4;
/// Hard wall-clock cap for a single `cargo metadata` invocation. Beyond
/// this the result is discarded and the workspace enters the error toast
/// path.
pub(crate) const CARGO_METADATA_TIMEOUT: Duration = Duration::from_secs(10);
// ── HTTP constants ───────────────────────────────────────────────────

pub(crate) const GITHUB_API_BASE: &str = "https://api.github.com";
pub(crate) const GITHUB_GRAPHQL_URL: &str = "https://api.github.com/graphql";
pub(crate) const CRATES_IO_API_BASE: &str = "https://crates.io/api/v1";
pub(crate) const CRATES_IO_USER_AGENT: &str = "cargo-port";
pub(crate) const SERVICE_RETRY_SECS: u64 = 1;
/// Wait this long after the first `Unreachable` signal before surfacing
/// the "service unreachable" toast. If the service recovers inside the
/// window (probe succeeds or a real request lands), no toast is ever
/// shown — and the matching "back online" toast is suppressed too.
/// Absorbs single transient timeouts in a stream of fetches without
/// flapping the UI; a real outage surfaces after this delay.
pub(crate) const SERVICE_UNAVAILABLE_GRACE: Duration = Duration::from_secs(3);

// ── Time constants ───────────────────────────────────────────────────

pub(crate) const MINUTES_PER_DAY: u64 = 1_440;
pub(crate) const MINUTES_PER_HOUR: u64 = 60;
pub(crate) const SECONDS_PER_DAY: u64 = 86_400;
pub(crate) const SECONDS_PER_HOUR: u64 = 3_600;
pub(crate) const SECONDS_PER_MINUTE: u64 = 60;

// ── Watcher constants ─────────────────────────────────────────────────

/// Wait for build/clean activity to settle before recalculating.
pub(crate) const DEBOUNCE_DURATION: Duration = Duration::from_millis(500);

/// Maximum time before forcing a recalc even if events keep arriving.
pub(crate) const MAX_WAIT: Duration = Duration::from_secs(1);

/// Extra settling time for new project directories (e.g. `cargo init`).
pub(crate) const NEW_PROJECT_DEBOUNCE: Duration = Duration::from_secs(2);

/// How often the watcher thread checks for expired timers.
pub(crate) const POLL_INTERVAL: Duration = Duration::from_millis(500);
pub(crate) const WATCHER_DISK_CONCURRENCY: usize = 2;
pub(crate) const WATCHER_GIT_CONCURRENCY: usize = 2;

// ── Lint history constants ───────────────────────────────────────────

pub(crate) const LINTS_LATEST_JSON: &str = "latest.json";
pub(crate) const LINTS_HISTORY_JSONL: &str = "history.jsonl";
/// Marker file at the lint cache root. Present iff the user paused lint work;
/// read at startup to resume a paused session paused after a restart.
pub(crate) const LINTS_PAUSED_MARKER: &str = "paused";

/// A `started` entry older than this is considered stale (crashed watcher).
pub(crate) const STALE_TIMEOUT: Duration = Duration::from_mins(30);

// ── Config constants ──────────────────────────────────────────────────

pub(crate) const APP_NAME: &str = "cargo-port";
pub(crate) const CLIPPY_LINT_COMMAND_NAME: &str = "clippy";
pub(crate) const CONFIG_FILE: &str = "config.toml";
pub(crate) const DEFAULT_CLIPPY_LINT_COMMAND: &str = "cargo clippy --workspace --all-targets \
                                                      --all-features --manifest-path \
                                                      \"$MANIFEST_PATH\" -- -D warnings";
pub(crate) const KEYMAP_FILE: &str = "keymap.toml";
pub(crate) const MIN_CPU_POLL_MS: u64 = 250;

// src config
pub(crate) const BYTES_PER_GIB: u64 = BYTES_PER_MIB * 1024;
pub(crate) const BYTES_PER_KIB: u64 = 1024;
pub(crate) const BYTES_PER_MIB: u64 = BYTES_PER_KIB * 1024;
pub(crate) const DEFAULT_CACHE_SIZE: &str = "512 MiB";

// src sccache
pub(crate) const SCCACHE_BINARY: &str = "sccache";
pub(crate) const SCCACHE_BINARY_WINDOWS: &str = "sccache.exe";
pub(crate) const SCCACHE_STATS_ARG: &str = "--show-stats";
pub(crate) const WRAPPER_ENV_KEYS: &[&str] = &[
    "RUSTC_WRAPPER",
    "RUSTC_WORKSPACE_WRAPPER",
    "CARGO_BUILD_RUSTC_WRAPPER",
    "CARGO_BUILD_RUSTC_WORKSPACE_WRAPPER",
];