use trusty_common::session_naming::{PREFIX, leaf_slug_from_hint};
use super::new_session::{NewSessionRequest, Step, Target, request_for_registered};
use super::state::Input;
pub(crate) const NOT_A_PROJECT: &str =
"Ctrl-N names a session in a registered project — pick one, or press Enter to type a path";
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct NameStep {
request: NewSessionRequest,
typed: String,
}
pub(crate) fn open(slot: &mut Option<NameStep>, target: Option<&Target>) -> Step {
let (name, repo, checkout) = match target {
Some(Target::Registered {
name,
repo,
checkout,
}) => (name, repo, checkout),
Some(Target::Other) => return Step::Reject(NOT_A_PROJECT.to_string()),
None => return Step::Ignore,
};
match request_for_registered(name, repo, checkout.as_deref()) {
Ok(request) => {
*slot = Some(NameStep {
request,
typed: String::new(),
});
Step::Redraw
}
Err(message) => Step::Reject(message),
}
}
pub(crate) fn route(slot: &mut Option<NameStep>, input: Input) -> Option<Step> {
let step = slot.as_mut()?.apply(input);
if step == Step::Cancel {
*slot = None;
return Some(Step::Redraw);
}
Some(step)
}
impl NameStep {
pub(crate) fn typed(&self) -> &str {
&self.typed
}
pub(crate) fn label(&self) -> &str {
&self.request.label
}
pub(crate) fn preview(&self) -> Option<String> {
let slug = leaf_slug_from_hint(&self.typed);
(!slug.is_empty()).then(|| format!("{PREFIX}{slug}-NN"))
}
pub(crate) fn apply(&mut self, input: Input) -> Step {
match input {
Input::Escape => Step::Cancel,
Input::Char(c) => {
self.typed.push(c);
Step::Redraw
}
Input::Backspace => match self.typed.pop() {
Some(_) => Step::Redraw,
None => Step::Ignore,
},
Input::Enter => {
let slug = leaf_slug_from_hint(&self.typed);
if slug.is_empty() {
return Step::Reject(format!(
"'{}' has no letters or digits to name a session with — \
type a name, or Esc to go back",
self.typed.trim()
));
}
Step::Create(NewSessionRequest {
name_hint: Some(slug),
..self.request.clone()
})
}
_ => Step::Ignore,
}
}
}
pub(crate) fn created_message(request: &NewSessionRequest) -> String {
match request.name_hint.as_deref() {
Some(slug) => format!("new session named {slug} in {}", request.label),
None => format!("new session in {}", request.label),
}
}