| Crates.io | sysuri |
| lib.rs | sysuri |
| version | 0.4.0 |
| created_at | 2025-12-27 02:52:22.082772+00 |
| updated_at | 2025-12-27 02:55:02.905508+00 |
| description | A cross-platform crate for registering custom URIs with the OS |
| homepage | |
| repository | https://github.com/Far-Beyond-Pulsar/sysuri |
| max_upload_size | |
| id | 2006611 |
| size | 63,138 |
A cross-platform Rust crate for registering custom URI schemes with the operating system.
Add this to your Cargo.toml:
[dependencies]
sysuri = "0.1"
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");
}
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...
}
use sysuri::parse_args;
fn main() {
if let Some(uri) = parse_args() {
println!("Launched with URI: {}", uri);
// Handle the URI...
return;
}
// Normal startup...
}
On Windows, sysuri registers URI schemes in HKEY_CURRENT_USER\Software\Classes, which doesn't require administrator privileges.
Testing:
start myapp://test/path
On macOS, sysuri creates a minimal .app bundle in ~/Applications with the appropriate Info.plist configuration.
Testing:
open myapp://test/path
On Linux, sysuri creates a .desktop file in ~/.local/share/applications/ and registers it using xdg-mime.
Testing:
xdg-open myapp://test/path
The crate includes several examples demonstrating different usage patterns:
cargo run --example basic
Demonstrates simple URI scheme registration and verification.
cargo run --example multiple_uris
Shows how to register multiple related URI schemes (e.g., myapp://, myapp-dev://, myapp-secure://).
cargo run --example callback_handler
Demonstrates the callback-based URI handling system with URI parsing.
register(scheme: &UriScheme) -> Result<()> - Register a URI schemeunregister(scheme: &str) -> Result<()> - Unregister a URI schemeis_registered(scheme: &str) -> Result<bool> - Check if a scheme is registeredregister_handler(scheme: &str, handler: impl UriHandler) - Register a URI handlerhandle_uri(uri: &str) -> Result<()> - Handle a URI using registered handlersshould_handle_uri() -> Result<bool> - Check and handle URI from command-line argsparse_args() -> Option<String> - Extract URI from command-line argumentsextract_scheme(uri: &str) -> Option<&str> - Extract scheme from a URIUriScheme - Represents a custom URI scheme registrationUriHandler - Trait for implementing URI handlersFnHandler - Function-based URI handler implementationYou 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...
}
}
let scheme = UriScheme::new("myapp", "My App", exe)
.with_icon(PathBuf::from("/path/to/icon.png"));
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!");
}
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),
}
According to RFC 3986, URI schemes must:
+, -, or .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.
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.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.