use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ts_rs::TS)]
#[ts(export)]
pub enum CommandSource {
Builtin,
Plugin(String),
}
#[derive(Debug, Clone, Serialize, Deserialize, ts_rs::TS)]
#[ts(export)]
pub struct Command {
pub name: String,
pub description: String,
pub action_name: String,
pub plugin_name: String,
pub custom_contexts: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ts_rs::TS)]
#[serde(deny_unknown_fields)]
#[ts(export, rename = "PromptSuggestion")]
pub struct Suggestion {
pub text: String,
#[serde(default)]
#[ts(optional)]
pub description: Option<String>,
#[serde(default)]
#[ts(optional)]
pub value: Option<String>,
#[serde(default)]
#[ts(optional)]
pub disabled: Option<bool>,
#[serde(default)]
#[ts(optional)]
pub keybinding: Option<String>,
#[serde(skip)]
#[ts(skip)]
pub source: Option<CommandSource>,
}
#[cfg(feature = "plugins")]
impl<'js> rquickjs::FromJs<'js> for Suggestion {
fn from_js(_ctx: &rquickjs::Ctx<'js>, value: rquickjs::Value<'js>) -> rquickjs::Result<Self> {
rquickjs_serde::from_value(value).map_err(|e| rquickjs::Error::FromJs {
from: "object",
to: "Suggestion",
message: Some(e.to_string()),
})
}
}
impl Suggestion {
pub fn new(text: String) -> Self {
Self {
text,
description: None,
value: None,
disabled: None,
keybinding: None,
source: None,
}
}
pub fn is_disabled(&self) -> bool {
self.disabled.unwrap_or(false)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_disabled_reflects_disabled_field() {
let mut s = Suggestion::new("foo".into());
assert!(!s.is_disabled(), "None defaults to enabled");
s.disabled = Some(false);
assert!(!s.is_disabled());
s.disabled = Some(true);
assert!(s.is_disabled());
}
#[cfg(feature = "plugins")]
#[test]
fn suggestion_from_js_decodes_distinguishing_fields() {
use rquickjs::{Context, FromJs, Runtime, Value};
let rt = Runtime::new().unwrap();
let ctx = Context::full(&rt).unwrap();
ctx.with(|ctx| {
let v: Value = ctx
.eval::<Value, _>(b"({text: 'hello', description: 'world'})".as_slice())
.unwrap();
let got = Suggestion::from_js(&ctx, v).unwrap();
assert_eq!(got.text, "hello");
assert_eq!(got.description.as_deref(), Some("world"));
});
}
}