Skip to main content

wisp_core/
action.rs

1use std::path::{Path, PathBuf};
2
3use crate::{Candidate, CandidateMetadata};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum Action {
7    Open,
8    SwitchSession,
9    CreateOrSwitchSession,
10    OpenShellHere,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum CandidateAction {
15    Open,
16    SwitchSession,
17    CreateOrSwitchSession,
18    OpenShellHere,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub enum ResolvedAction {
23    SwitchSession {
24        session_name: String,
25    },
26    CreateOrSwitchSession {
27        session_name: String,
28        directory: PathBuf,
29    },
30    OpenShellHere {
31        directory: PathBuf,
32    },
33}
34
35#[must_use]
36pub fn resolve_action(candidate: &Candidate) -> Option<ResolvedAction> {
37    match (&candidate.action, &candidate.metadata) {
38        (CandidateAction::SwitchSession, CandidateMetadata::Session(metadata)) => {
39            Some(ResolvedAction::SwitchSession {
40                session_name: metadata.session_name.clone(),
41            })
42        }
43        (CandidateAction::CreateOrSwitchSession, CandidateMetadata::Directory(metadata)) => {
44            Some(ResolvedAction::CreateOrSwitchSession {
45                session_name: sanitize_session_name(&metadata.full_path),
46                directory: metadata.full_path.clone(),
47            })
48        }
49        (CandidateAction::OpenShellHere, CandidateMetadata::Directory(metadata)) => {
50            Some(ResolvedAction::OpenShellHere {
51                directory: metadata.full_path.clone(),
52            })
53        }
54        _ => None,
55    }
56}
57
58#[must_use]
59pub fn sanitize_session_name(path: &Path) -> String {
60    let raw_name = path
61        .file_name()
62        .and_then(|name| name.to_str())
63        .filter(|name| !name.is_empty())
64        .unwrap_or("wisp");
65
66    let sanitized: String = raw_name
67        .chars()
68        .map(|character| {
69            if character.is_ascii_alphanumeric() || matches!(character, '-' | '_') {
70                character
71            } else {
72                '-'
73            }
74        })
75        .collect();
76
77    let trimmed = sanitized.trim_matches('-');
78    if trimmed.is_empty() {
79        "wisp".to_string()
80    } else {
81        trimmed.to_string()
82    }
83}