#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Capability {
Inspect,
Handoff,
}
#[derive(Debug, Clone, Copy)]
pub struct NativeCommand {
pub name: &'static str,
pub capability: &'static str,
pub kind: Capability,
pub summary: &'static str,
}
pub fn commands() -> &'static [NativeCommand] {
&[
NativeCommand {
name: "platform",
capability: "platform",
kind: Capability::Inspect,
summary: "Which operating system the package is running on.",
},
NativeCommand {
name: "app_version",
capability: "app-version",
kind: Capability::Inspect,
summary: "The installed application's version.",
},
NativeCommand {
name: "app_data_dir",
capability: "app-data-dir",
kind: Capability::Inspect,
summary: "Where this installation keeps its data, for showing the user.",
},
NativeCommand {
name: "open_external",
capability: "open-external",
kind: Capability::Handoff,
summary: "Open an http, https or mailto URL in the user's own browser or mail client.",
},
NativeCommand {
name: "choose_file",
capability: "choose-file",
kind: Capability::Handoff,
summary: "Open the platform file picker and return what the user chose.",
},
]
}
pub fn is_allowed(name: &str) -> bool {
commands().iter().any(|command| command.name == name)
}
pub fn capability_names() -> Vec<&'static str> {
commands().iter().map(|c| c.capability).collect()
}
pub fn is_external_url(url: &str) -> bool {
let url = url.trim();
if url.is_empty() || url.chars().any(|c| c.is_control()) {
return false;
}
let Some((scheme, rest)) = url.split_once(':') else {
return false;
};
if rest.is_empty() {
return false;
}
match scheme.to_ascii_lowercase().as_str() {
"http" | "https" => rest.starts_with("//") && rest.len() > 2 && !rest.starts_with("///"),
"mailto" => true,
_ => false,
}
}