sysuri 0.1.0

A cross-platform crate for registering custom URIs with the OS
Documentation

sysuri

A cross-platform Rust crate for registering custom URI schemes with the operating system.

Crates.io Documentation License: MIT

Features

  • Cross-platform support: Windows, macOS, and Linux
  • Simple API: Register and unregister URI schemes with just a few lines of code
  • Callback-based handling: Define handlers for incoming URI requests
  • No unsafe code: Built with safety in mind
  • Well-documented: Comprehensive API documentation and examples
  • Lightweight: Minimal dependencies

Installation

Add this to your Cargo.toml:

[dependencies]
sysuri = "0.1"

Quick Start

Basic Registration

use sysuri::{UriScheme, register};
use std::env;

fn main() {
    // Get the current executable path
    let exe = env::current_exe().unwrap();

    // Create a URI scheme
    let scheme = UriScheme::new(
        "myapp",
        "My Application Protocol",
        exe
    );

    // Register it with the OS
    register(&scheme).unwrap();

    println!("URI scheme registered! Try: myapp://test");
}

Handling URI Callbacks

When your application is launched via a custom URI, the URI is passed as a command-line argument:

use sysuri::{register_handler, should_handle_uri, FnHandler};

fn main() {
    // Register a handler for your scheme
    register_handler("myapp", FnHandler::new(|uri| {
        println!("Received URI: {}", uri);
        // Parse and handle the URI...
    }));

    // Check if we should handle a URI
    match should_handle_uri() {
        Ok(true) => {
            println!("Handled URI, exiting...");
            return;
        }
        Ok(false) => {
            println!("Normal application startup");
        }
        Err(e) => {
            eprintln!("Error: {}", e);
        }
    }

    // Continue with normal application logic...
}

Alternative: Manual URI Parsing

use sysuri::parse_args;

fn main() {
    if let Some(uri) = parse_args() {
        println!("Launched with URI: {}", uri);
        // Handle the URI...
        return;
    }

    // Normal startup...
}

Platform-Specific Behavior

Windows

On Windows, sysuri registers URI schemes in HKEY_CURRENT_USER\Software\Classes, which doesn't require administrator privileges.

Testing:

start myapp://test/path

macOS

On macOS, sysuri creates a minimal .app bundle in ~/Applications with the appropriate Info.plist configuration.

Testing:

open myapp://test/path

Linux

On Linux, sysuri creates a .desktop file in ~/.local/share/applications/ and registers it using xdg-mime.

Testing:

xdg-open myapp://test/path

Examples

The crate includes several examples demonstrating different usage patterns:

Basic Registration

cargo run --example basic

Demonstrates simple URI scheme registration and verification.

Multiple URI Schemes

cargo run --example multiple_uris

Shows how to register multiple related URI schemes (e.g., myapp://, myapp-dev://, myapp-secure://).

Callback Handlers

cargo run --example callback_handler

Demonstrates the callback-based URI handling system with URI parsing.

API Overview

Core Functions

  • register(scheme: &UriScheme) -> Result<()> - Register a URI scheme
  • unregister(scheme: &str) -> Result<()> - Unregister a URI scheme
  • is_registered(scheme: &str) -> Result<bool> - Check if a scheme is registered

Handler Functions

  • register_handler(scheme: &str, handler: impl UriHandler) - Register a URI handler
  • handle_uri(uri: &str) -> Result<()> - Handle a URI using registered handlers
  • should_handle_uri() -> Result<bool> - Check and handle URI from command-line args

Utility Functions

  • parse_args() -> Option<String> - Extract URI from command-line arguments
  • extract_scheme(uri: &str) -> Option<&str> - Extract scheme from a URI

Types

  • UriScheme - Represents a custom URI scheme registration
  • UriHandler - Trait for implementing URI handlers
  • FnHandler - Function-based URI handler implementation

Advanced Usage

Custom Handler Implementation

You can implement the UriHandler trait for more complex handling:

use sysuri::UriHandler;

struct MyHandler {
    // Your state...
}

impl UriHandler for MyHandler {
    fn handle_uri(&self, uri: &str) {
        // Custom handling logic...
    }
}

With Icon (Windows/Linux)

let scheme = UriScheme::new("myapp", "My App", exe)
    .with_icon(PathBuf::from("/path/to/icon.png"));

Conditional Registration

use sysuri::{is_registered, register};

let scheme_name = "myapp";

if !is_registered(scheme_name)? {
    println!("Registering for the first time...");
    register(&scheme)?;
} else {
    println!("Already registered!");
}

Error Handling

The crate uses a comprehensive error type covering common failure scenarios:

use sysuri::{register, Error};

match register(&scheme) {
    Ok(_) => println!("Success!"),
    Err(Error::InvalidScheme(s)) => eprintln!("Invalid scheme: {}", s),
    Err(Error::PermissionDenied(msg)) => eprintln!("Permission denied: {}", msg),
    Err(Error::Platform(msg)) => eprintln!("Platform error: {}", msg),
    Err(e) => eprintln!("Other error: {}", e),
}

URI Scheme Naming

According to RFC 3986, URI schemes must:

  • Start with a letter
  • Contain only letters, digits, +, -, or .
  • Be case-insensitive (lowercase is recommended)

Valid examples: myapp, my-app, app.protocol, my+app

Invalid examples: my_app, 123app, my app

The crate validates schemes automatically and returns Error::InvalidScheme for invalid names.

Testing

Run the test suite:

cargo test

Note: Some platform-specific tests may require appropriate permissions and can modify system settings. They use unique scheme names to avoid conflicts.

Security Considerations

  • URI schemes are registered per-user (not system-wide) on all platforms
  • The crate validates URI scheme names according to RFC 3986
  • Executable paths are verified to exist before registration
  • No elevation/admin privileges required

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Inspired by the need for a simple, cross-platform URI registration solution
  • Built with safety and usability in mind

Changelog

Version 0.1.0 (Initial Release)

  • Cross-platform URI scheme registration (Windows, macOS, Linux)
  • Callback-based URI handling system
  • Comprehensive examples and documentation
  • Full test coverage