use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UriScheme {
pub scheme: String,
pub description: String,
pub executable: PathBuf,
pub icon: Option<PathBuf>,
}
impl UriScheme {
pub fn new<S: Into<String>>(scheme: S, description: S, executable: PathBuf) -> Self {
Self {
scheme: scheme.into(),
description: description.into(),
executable,
icon: None,
}
}
pub fn with_icon(mut self, icon: PathBuf) -> Self {
self.icon = Some(icon);
self
}
pub fn is_valid_scheme(&self) -> bool {
if self.scheme.is_empty() {
return false;
}
let mut chars = self.scheme.chars();
if let Some(first) = chars.next() {
if !first.is_ascii_alphabetic() {
return false;
}
}
chars.all(|c| c.is_ascii_alphanumeric() || c == '+' || c == '-' || c == '.')
}
pub fn full_uri(&self) -> String {
format!("{}://", self.scheme)
}
}
pub trait UriHandler: Send + Sync {
fn handle_uri(&self, uri: &str);
}
pub struct FnHandler<F>
where
F: Fn(&str) + Send + Sync,
{
handler: F,
}
impl<F> FnHandler<F>
where
F: Fn(&str) + Send + Sync,
{
pub fn new(handler: F) -> Self {
Self { handler }
}
}
impl<F> UriHandler for FnHandler<F>
where
F: Fn(&str) + Send + Sync,
{
fn handle_uri(&self, uri: &str) {
(self.handler)(uri)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_schemes() {
let scheme = UriScheme::new("myapp", "Test", PathBuf::from("/test"));
assert!(scheme.is_valid_scheme());
let scheme = UriScheme::new("my-app", "Test", PathBuf::from("/test"));
assert!(scheme.is_valid_scheme());
let scheme = UriScheme::new("my+app", "Test", PathBuf::from("/test"));
assert!(scheme.is_valid_scheme());
let scheme = UriScheme::new("my.app", "Test", PathBuf::from("/test"));
assert!(scheme.is_valid_scheme());
}
#[test]
fn test_invalid_schemes() {
let scheme = UriScheme::new("", "Test", PathBuf::from("/test"));
assert!(!scheme.is_valid_scheme());
let scheme = UriScheme::new("1myapp", "Test", PathBuf::from("/test"));
assert!(!scheme.is_valid_scheme());
let scheme = UriScheme::new("my_app", "Test", PathBuf::from("/test"));
assert!(!scheme.is_valid_scheme());
let scheme = UriScheme::new("my app", "Test", PathBuf::from("/test"));
assert!(!scheme.is_valid_scheme());
}
#[test]
fn test_full_uri() {
let scheme = UriScheme::new("myapp", "Test", PathBuf::from("/test"));
assert_eq!(scheme.full_uri(), "myapp://");
}
}