rootle 0.13.1

Modal TUI for browsing remote source-control systems from the terminal
Documentation
//! Whitelisted action observations; no action Debug dumps.
use super::{describe_error, describe_key_with, full, text_with};
use crate::action::{Action, DeclarationState};
use rootle_trace::EventKind;
use serde_json::{Value, json};

/// Action dispatch: variant name plus whitelisted identity (repos,
/// paths, shas, generations, counts). Query/command/preview/line/byte
/// contents are lengths; Full adds only query/command text.
pub(crate) fn record_action(action: &Action) {
    rootle_trace::record_with(EventKind::Action, || describe_action(action));
}

pub(super) fn describe_action(action: &Action) -> Value {
    let full = full();
    match action {
        Action::Noop => json!({"action": "noop"}),
        Action::Quit => json!({"action": "quit"}),
        Action::MoveUp => json!({"action": "move_up"}),
        Action::MoveDown => json!({"action": "move_down"}),
        Action::DrillIn => json!({"action": "drill_in"}),
        Action::DrillOut => json!({"action": "drill_out"}),
        Action::PreviewLineUp => json!({"action": "preview_line_up"}),
        Action::PreviewLineDown => json!({"action": "preview_line_down"}),
        Action::EnterSearch => json!({"action": "enter_search"}),
        Action::CommitFilter => json!({"action": "commit_filter"}),
        Action::ClearFilter => json!({"action": "clear_filter"}),
        Action::LeaderFindInFile => json!({"action": "leader_find_in_file"}),
        Action::UpdateFind => json!({"action": "update_find"}),
        Action::CommitFind => json!({"action": "commit_find"}),
        Action::CancelFind => json!({"action": "cancel_find"}),
        Action::FindNext => json!({"action": "find_next"}),
        Action::FindPrev => json!({"action": "find_prev"}),
        Action::Leader => json!({"action": "leader"}),
        Action::LeaderSearch => json!({"action": "leader_search"}),
        Action::LeaderFileFind => json!({"action": "leader_file_find"}),
        Action::LeaderGrep => json!({"action": "leader_grep"}),
        Action::LeaderRefs => json!({"action": "leader_refs"}),
        Action::LeaderPreview => json!({"action": "leader_preview"}),
        Action::ExitPreview => json!({"action": "exit_preview"}),
        Action::LeaderHistory => json!({"action": "leader_history"}),
        Action::LeaderRepositoryHistory => json!({"action": "leader_repository_history"}),
        Action::BlameToggle => json!({"action": "blame_toggle"}),
        Action::PreviewCopy => json!({"action": "preview_copy"}),
        Action::PreviewEnter => json!({"action": "preview_enter"}),
        Action::PreviewVisualToggle => json!({"action": "preview_visual_toggle"}),
        Action::LeaderQuit => json!({"action": "leader_quit"}),
        Action::HistoryUp => json!({"action": "history_up"}),
        Action::HistoryDown => json!({"action": "history_down"}),
        Action::HistoryOpen => json!({"action": "history_open"}),
        Action::HistoryClose => json!({"action": "history_close"}),
        Action::HistoryFilterBegin => json!({"action": "history_filter_begin"}),
        Action::HistoryYank => json!({"action": "history_yank"}),
        Action::CommitDive => json!({"action": "commit_dive"}),
        Action::CommitUp => json!({"action": "commit_up"}),
        Action::CommitDown => json!({"action": "commit_down"}),
        Action::CommitOpen => json!({"action": "commit_open"}),
        Action::CommitClose => json!({"action": "commit_close"}),
        Action::CommitStepNext => json!({"action": "commit_step_next"}),
        Action::CommitStepPrev => json!({"action": "commit_step_prev"}),
        Action::CommitYank => json!({"action": "commit_yank"}),
        Action::CommitFilterBegin => json!({"action": "commit_filter_begin"}),
        Action::CommitFirst => json!({"action": "commit_first"}),
        Action::CommitLast => json!({"action": "commit_last"}),
        Action::CommitFocus => json!({"action": "commit_focus"}),
        Action::CommitLeft => json!({"action": "commit_left"}),
        Action::CommitRight => json!({"action": "commit_right"}),
        Action::CommitSearchBegin => json!({"action":"commit_search_begin"}),
        Action::CommitSearchNext => json!({"action":"commit_search_next"}),
        Action::CommitSearchPrevious => json!({"action":"commit_search_previous"}),
        Action::CommitCopy => json!({"action":"commit_copy"}),
        Action::CommitPage { forward, half } => {
            json!({"action":"commit_page","forward":forward,"half":half})
        }
        Action::CommitSearchKey(key) => {
            json!({"action":"commit_search_key","key":describe_key_with(full,key)})
        }
        Action::SearchYank => json!({"action": "search_yank"}),
        Action::DeclarationAccept => json!({"action": "declaration_accept"}),
        Action::DeclarationRetry => json!({"action": "declaration_retry"}),
        Action::DeclarationEditConfig => json!({"action": "declaration_edit_config"}),
        Action::DeclarationDecline => json!({"action": "declaration_decline"}),
        Action::ClosePopup => json!({"action": "close_popup"}),
        Action::KeybindsPopup => json!({"action": "keybinds_popup"}),
        Action::CommandLine => json!({"action": "command_line"}),
        Action::Visual => json!({"action": "visual"}),
        Action::ExitVisual => json!({"action": "exit_visual"}),
        Action::ToggleSelect => json!({"action": "toggle_select"}),
        Action::LeaderYank => json!({"action": "leader_yank"}),
        Action::ClearMarks => json!({"action": "clear_marks"}),
        Action::DeleteMarked => json!({"action": "delete_marked"}),
        Action::LeaderReload => json!({"action": "leader_reload"}),
        Action::CloseSearchView => json!({"action": "close_search_view"}),
        Action::OpenSelected => json!({"action": "open_selected"}),

        Action::RefsPreview(name) => json!({"action": "refs_preview", "ref": name}),
        Action::RefsCommit(name) => json!({"action": "refs_commit", "ref": name}),
        Action::HistoryFilterKey(key) => json!({
            "action": "history_filter_key",
            "key": describe_key_with(full, key),
        }),
        Action::CommitFilterKey(key) => json!({
            "action": "commit_filter_key",
            "key": describe_key_with(full, key),
        }),
        Action::DeclarationState(state) => json!({
            "action": "declaration_state",
            "state": match state {
                DeclarationState::Installing => "installing",
                DeclarationState::Failed(_) => "failed",
            },
            "message": match state {
                DeclarationState::Installing => Value::Null,
                DeclarationState::Failed(message) => text_with(full, message),
            },
        }),
        Action::RunCommand(command) => json!({
            "action": "run_command",
            "command": text_with(full, command),
        }),
        // Never a config dump: the fact of applying settings.
        Action::ApplySettings(_) => json!({"action": "apply_settings"}),
        Action::RunClone { repos, dest } => json!({
            "action": "run_clone",
            "repos": repos.len(),
            "dest": dest.display().to_string(),
        }),
        Action::GlobalSearchSubmitted {
            kind,
            query,
            scope,
            extension,
        } => json!({
            "action": "global_search_submitted",
            "kind": kind.slug(),
            "query": text_with(full, query),
            "scope": scope,
            "extension": text_with(full, extension),
        }),
        Action::GlobalSearchResults {
            hits,
            clipped,
            index,
            client_filtered,
            unfiltered,
        } => json!({
            "action": "global_search_results",
            "hits": hits.len(),
            "clipped": clipped,
            "index_as_of": index.is_some(),
            "client_filtered": client_filtered,
            "unfiltered": unfiltered.len(),
        }),
        Action::GlobalSearchDelta { hits } => json!({
            "action": "global_search_delta",
            "hits": hits.len(),
        }),
        Action::GlobalSearchFailed { error } => json!({
            "action": "global_search_failed",
            "error": describe_error(error),
        }),
        Action::LoadHitContext { hit, query } => json!({
            "action": "load_hit_context",
            "repo": hit.repo,
            "path": hit.path,
            "sha": hit.sha,
            "query": text_with(full, query),
        }),
        Action::HitContextLoaded {
            repo,
            path,
            sha,
            line,
            preview,
            match_count,
        } => json!({
            "action": "hit_context_loaded",
            "repo": repo,
            "path": path,
            "sha": sha,
            "line": line,
            "preview_lines": preview.len(),
            "matches": match_count,
        }),
        Action::OpenSearchHit(hit) => json!({
            "action": "open_search_hit",
            "repo": hit.repo,
            "path": hit.path,
            "sha": hit.sha,
            "mock": hit.sha.is_empty(),
        }),
        Action::LoadHitFile { hit } => json!({
            "action": "load_hit_file",
            "repo": hit.repo,
            "path": hit.path,
            "sha": hit.sha,
        }),
        Action::HitFileLoaded {
            repo,
            path,
            sha,
            lang,
            lines,
        } => json!({
            "action": "hit_file_loaded",
            "repo": repo,
            "path": path,
            "sha": sha,
            "lang": lang,
            "lines": lines.len(),
        }),
        Action::HitFileFailed { sha, error } => json!({
            "action": "hit_file_failed",
            "sha": sha,
            "error": describe_error(error),
        }),
        Action::SearchSubmitted(query) => json!({
            "action": "search_submitted",
            "query": text_with(full, query),
        }),
        Action::SearchResults { items } => json!({
            "action": "search_results",
            "items": items.len(),
        }),
        Action::SearchFailed { error } => json!({
            "action": "search_failed",
            "error": describe_error(error),
        }),
        Action::OrgSelected(org) => json!({"action": "org_selected", "org": org}),
        Action::LoadOrgRepos(org) => json!({"action": "load_org_repos", "org": org}),
        Action::OrgReposLoaded { request, repos } => json!({
            "action": "org_repos_loaded",
            "request": request,
            "repos": repos.len(),
        }),
        Action::OrgReposFailed { request, error } => json!({
            "action": "org_repos_failed",
            "request": request,
            "error": describe_error(error),
        }),
        Action::LoadRepoTree { owner, name } => json!({
            "action": "load_repo_tree",
            "repo": format!("{owner}/{name}"),
        }),
        Action::TreeLoaded {
            request,
            entries,
            truncated,
            branch,
        } => json!({
            "action": "tree_loaded",
            "request": request,
            "entries": entries.len(),
            "truncated": truncated,
            "branch": branch,
        }),
        Action::TreeFailed { request, error } => json!({
            "action": "tree_failed",
            "request": request,
            "error": describe_error(error),
        }),
        Action::LoadBlob { sha, name } => json!({
            "action": "load_blob",
            "sha": sha,
            "path": name,
        }),
        Action::BlobLoaded { sha, name, bytes } => json!({
            "action": "blob_loaded",
            "sha": sha,
            "path": name,
            "bytes": bytes.len(),
        }),
        Action::BlobFailed { sha, error } => json!({
            "action": "blob_failed",
            "sha": sha,
            "error": describe_error(error),
        }),
        Action::HitContextFailed { sha, error } => json!({
            "action": "hit_context_failed",
            "sha": sha,
            "error": describe_error(error),
        }),
        Action::HitContextMissing { sha } => json!({
            "action": "hit_context_missing",
            "sha": sha,
        }),
        Action::HitContextDebounceFired {
            timer_gen,
            hit,
            query,
        } => json!({
            "action": "hit_context_debounce_fired",
            "timer_gen": timer_gen,
            "repo": hit.repo,
            "path": hit.path,
            "sha": hit.sha,
            "query": text_with(full, query),
        }),
        Action::RepoSelected { owner, name } => json!({
            "action": "repo_selected",
            "repo": format!("{owner}/{name}"),
        }),
    }
}