use schemars::JsonSchema;
use serde::Deserialize;
fn deserialize_optional_object<'de, D>(
deserializer: D,
) -> Result<Option<serde_json::Value>, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = Option::<serde_json::Value>::deserialize(deserializer)?;
match value {
None | Some(serde_json::Value::Object(_)) => Ok(value),
Some(_) => Err(serde::de::Error::custom(
"`args` must be a JSON object of {parameter_name: value} (got a scalar or array)",
)),
}
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct RegistryParams {
pub query: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct InvokeCommandParams {
pub command: String,
#[serde(default, deserialize_with = "deserialize_optional_object")]
pub args: Option<serde_json::Value>,
#[serde(alias = "window", alias = "window_label")]
pub webview_label: Option<String>,
}
#[derive(Debug, Deserialize, JsonSchema, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum AppDir {
Data,
Config,
Log,
LocalData,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct ListAppDirParams {
pub directory: Option<AppDir>,
pub path: Option<String>,
pub pattern: Option<String>,
pub max_depth: Option<u32>,
}
#[derive(Debug, Deserialize, JsonSchema)]
pub struct ReadAppFileParams {
pub directory: Option<AppDir>,
pub path: String,
pub max_bytes: Option<usize>,
pub binary: Option<bool>,
}
#[derive(Debug, Deserialize, JsonSchema)]
#[cfg_attr(not(feature = "sqlite"), allow(dead_code))]
pub struct QueryDbParams {
pub path: Option<String>,
#[serde(alias = "sql")]
pub query: String,
pub params: Option<Vec<serde_json::Value>>,
pub max_rows: Option<usize>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn query_db_accepts_sql_alias() {
for key in ["query", "sql"] {
let json = format!(r#"{{"{key}":"SELECT 1"}}"#);
let p: QueryDbParams = serde_json::from_str(&json)
.unwrap_or_else(|e| panic!("key `{key}` must deserialize: {e}"));
assert_eq!(
p.query, "SELECT 1",
"key `{key}` must populate the query field"
);
}
}
}