use crate::context::Context;
pub type ConditionFn = dyn Fn(&Context) -> bool + Send + Sync;
pub struct ActiveHelp {
pub message: String,
pub condition: Option<std::sync::Arc<ConditionFn>>,
}
impl ActiveHelp {
#[must_use]
pub fn new<S: Into<String>>(message: S) -> Self {
Self {
message: message.into(),
condition: None,
}
}
#[must_use]
pub fn with_condition<S, F>(message: S, condition: F) -> Self
where
S: Into<String>,
F: Fn(&Context) -> bool + Send + Sync + 'static,
{
Self {
message: message.into(),
condition: Some(std::sync::Arc::new(condition)),
}
}
#[must_use]
pub fn should_display(&self, ctx: &Context) -> bool {
self.condition
.as_ref()
.map_or(true, |condition| condition(ctx))
}
}
impl Clone for ActiveHelp {
fn clone(&self) -> Self {
Self {
message: self.message.clone(),
condition: self.condition.clone(),
}
}
}
impl std::fmt::Debug for ActiveHelp {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ActiveHelp")
.field("message", &self.message)
.field("condition", &self.condition.is_some())
.finish()
}
}
#[derive(Clone, Debug)]
pub struct ActiveHelpConfig {
pub show_on_double_tab: bool,
pub show_on_no_completions: bool,
pub disabled: bool,
pub disable_env_var: Option<String>,
}
impl Default for ActiveHelpConfig {
fn default() -> Self {
Self {
show_on_double_tab: true,
show_on_no_completions: true,
disabled: false,
disable_env_var: Some("COBRA_ACTIVE_HELP".to_string()), }
}
}
impl ActiveHelpConfig {
#[must_use]
pub fn is_enabled(&self) -> bool {
if self.disabled {
return false;
}
if let Some(ref env_var) = self.disable_env_var {
if let Ok(value) = std::env::var(env_var) {
return !matches!(value.to_lowercase().as_str(), "0" | "false");
}
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_active_help_new() {
let help = ActiveHelp::new("Test message");
assert_eq!(help.message, "Test message");
assert!(help.condition.is_none());
}
#[test]
fn test_active_help_with_condition() {
let help = ActiveHelp::with_condition("Conditional help", |_ctx| true);
assert_eq!(help.message, "Conditional help");
assert!(help.condition.is_some());
}
#[test]
fn test_should_display() {
let ctx = Context::new(vec![]);
let help = ActiveHelp::new("Always shown");
assert!(help.should_display(&ctx));
let help = ActiveHelp::with_condition("Also shown", |_| true);
assert!(help.should_display(&ctx));
let help = ActiveHelp::with_condition("Never shown", |_| false);
assert!(!help.should_display(&ctx));
}
#[test]
fn test_active_help_config_default() {
let config = ActiveHelpConfig::default();
assert!(config.show_on_double_tab);
assert!(config.show_on_no_completions);
assert!(!config.disabled);
assert_eq!(
config.disable_env_var,
Some("COBRA_ACTIVE_HELP".to_string())
);
}
#[test]
fn test_active_help_config_is_enabled() {
let config = ActiveHelpConfig::default();
assert!(config.is_enabled());
let config = ActiveHelpConfig {
disabled: true,
..Default::default()
};
assert!(!config.is_enabled());
}
}