waterui-url 0.2.1

A modern UI framework for Rust
Documentation

waterui-url

Fast, zero-allocation URL parsing for WaterUI with compile-time validation and reactive fetching.

Overview

waterui-url provides a unified Url type that handles web URLs, local file paths, data URLs, and blob URLs with a consistent API. The library is designed for performance and safety, offering compile-time URL creation with validation, zero-allocation parsing using byte offsets, and seamless integration with WaterUI's reactive primitives.

Key features:

  • Compile-time URL creation: Create and validate URLs at compile time using const fn
  • Zero-allocation parsing: Parses URLs once, stores byte offsets to components, no intermediate allocations
  • Unified API: Single Url type for web URLs, local paths, data URLs, and blob URLs
  • O(1) component access: Scheme, host, port, path, query, and fragment are extracted during parsing
  • no_std compatible: Works without the standard library (with optional std feature for Path support)
  • Reactive integration: Built-in support for reactive URL fetching via nami signals

Installation

Add this to your Cargo.toml:

[dependencies]
waterui-url = "0.1.0"

For file path support (requires std):

[dependencies]
waterui-url = { version = "0.1.0", features = ["std"] }

Quick Start

use waterui_url::Url;

// Compile-time URL creation with validation
const API_ENDPOINT: Url = Url::new("https://api.example.com/v1/users");
const LOCAL_ASSET: Url = Url::new("/assets/logo.png");

fn main() {
    // Runtime parsing
    let url: Url = "https://example.com/api?key=value".parse().unwrap();

    println!("Host: {:?}", url.host());        // Some("example.com")
    println!("Path: {}", url.path());          // "/api"
    println!("Query: {:?}", url.query());      // Some("key=value")
}

Core Concepts

Url Type

The Url struct is a unified type that automatically detects and parses different URL kinds:

  • Web URLs: http://, https://, ftp://, ws://, wss://, etc.
  • Local file paths: Absolute (/home/user/file.txt) or relative (./images/photo.jpg)
  • Data URLs: data:text/plain;base64,SGVsbG8=
  • Blob URLs: blob:https://example.com/uuid

The parser runs once during construction and stores component offsets as u16 byte ranges, making subsequent access to URL parts O(1) with no additional parsing.

Compile-Time Validation

URLs created with Url::new() in const contexts are validated at compile time. Malformed URLs cause compilation errors:

// This compiles fine
const VALID: Url = Url::new("https://example.com");

// This fails at compile time: "Web URL must have a host"
const INVALID: Url = Url::new("https://");

Reactive Fetching

The fetch() method returns a reactive signal that can be watched for changes, integrating with WaterUI's reactive update system:

use waterui_url::Url;

let url = Url::parse("https://api.example.com/data.json").unwrap();
let fetched = url.fetch();
// Use with WaterUI's reactive primitives

Examples

Parsing Web URLs

use waterui_url::Url;

let url = Url::parse("https://user:pass@example.com:8080/api/v1?id=123#section").unwrap();

assert_eq!(url.scheme(), Some("https"));
assert_eq!(url.host(), Some("example.com"));
assert_eq!(url.port(), Some(8080));
assert_eq!(url.path(), "/api/v1");
assert_eq!(url.query(), Some("id=123"));
assert_eq!(url.fragment(), Some("section"));
assert_eq!(url.authority(), Some("user:pass@example.com:8080"));

Working with Local Paths

use waterui_url::Url;

let absolute = Url::new("/home/user/documents/file.pdf");
assert!(absolute.is_local());
assert!(absolute.is_absolute());
assert_eq!(absolute.extension(), Some("pdf"));
assert_eq!(absolute.filename(), Some("file.pdf"));

let relative = Url::new("./images/photo.jpg");
assert!(relative.is_relative());
assert_eq!(relative.extension(), Some("jpg"));

Creating Data URLs

use waterui_url::Url;

let data_url = Url::from_data("image/png", b"PNG binary data here...");
assert!(data_url.is_data());
assert_eq!(data_url.scheme(), Some("data"));
// URL is automatically base64-encoded
println!("{}", data_url);  // data:image/png;base64,UE5HIGJpbmFyeSBkYXRhIGhlcmUuLi4=

Joining URLs

use waterui_url::Url;

let base = Url::new("https://cdn.example.com/assets/");
let joined = base.join("images/logo.png");
assert_eq!(joined.as_str(), "https://cdn.example.com/assets/images/logo.png");

// Handles file paths too
let base_file = Url::new("https://example.com/path/file.html");
let joined_file = base_file.join("other.html");
assert_eq!(joined_file.as_str(), "https://example.com/path/other.html");

API Overview

Construction

  • Url::new(url: &'static str) -> Url - Create URL at compile time (const fn)
  • Url::parse(url: impl AsRef<str>) -> Option<Url> - Parse web URL at runtime
  • Url::from_file_path(path: impl AsRef<Path>) -> Url - Create from file path (requires std feature)
  • Url::from_file_path_str(path: impl Into<Str>) -> Url - Create from path string
  • Url::from_data(mime_type: &str, data: &[u8]) -> Url - Create base64-encoded data URL
  • FromStr trait - Parse any URL type from string

Type Checking

  • is_web() -> bool - Check if URL is a web URL (http/https/ftp/ws/wss)
  • is_local() -> bool - Check if URL is a local file path
  • is_data() -> bool - Check if URL is a data URL
  • is_blob() -> bool - Check if URL is a blob URL
  • is_absolute() -> bool - Check if URL or path is absolute
  • is_relative() -> bool - Check if URL or path is relative

Component Access

All component accessors are O(1) operations using pre-parsed byte offsets:

  • scheme() -> Option<&str> - URL scheme (e.g., "https", "file", "data")
  • host() -> Option<&str> - Host portion for web URLs
  • port() -> Option<u16> - Port number for web URLs (parsed as integer)
  • path() -> &str - Path component
  • query() -> Option<&str> - Query string without '?'
  • fragment() -> Option<&str> - Fragment without '#'
  • authority() -> Option<&str> - Full authority section (user:pass@host:port)
  • extension() -> Option<&str> - File extension if present
  • filename() -> Option<&str> - Filename from path

Manipulation

  • join(&self, path: &str) -> Url - Join URL with relative path
  • fetch(&self) -> Fetched - Get reactive signal for URL content
  • to_file_path(&self) -> Option<PathBuf> - Convert to file path (requires std feature)

Conversion

  • as_str(&self) -> &str - Get URL as string slice
  • into_string(self) -> String - Convert to owned String
  • inner(&self) -> Str - Get the underlying Str value
  • AsRef<str> - Automatic conversion to &str
  • Display - Format URL as string

Features

The crate supports the following Cargo features:

  • std (optional): Enables std::path::Path integration for from_file_path() and to_file_path() methods. Without this feature, the crate is no_std compatible.

Implementation Details

Zero-Allocation Architecture

The Url type stores the original URL string once and references its components using Span structs containing u16 start/end offsets. This design:

  • Parses the URL exactly once during construction
  • Stores component offsets, not copies of component strings
  • Returns string slices that reference the original URL
  • Uses only 2 bytes per component (start + end offset)
  • Supports URLs up to 65,535 bytes (reasonable for most use cases)

Const-Compatible Parser

The entire parsing implementation uses const-compatible operations (byte-level comparisons, loops with manual indexing) to enable compile-time URL creation and validation. The parser:

  • Validates web URL structure (requires scheme and host)
  • Checks port numbers are valid (digits only, max 5 digits)
  • Handles IPv6 addresses in brackets [::1]
  • Parses data URLs with MIME types and base64 encoding
  • Detects Windows vs Unix path conventions

Error Handling

The parse() function returns Result<Url, ParseError> for runtime parsing. The new() const fn panics on invalid URLs, enabling compile-time validation in const contexts.

Platform Support

This crate is no_std compatible by default. Enable the std feature for:

  • Path/PathBuf integration via from_file_path() and to_file_path()
  • std::error::Error trait implementation for ParseError

Windows, macOS, and Linux are all supported. The parser correctly handles platform-specific path conventions (backslashes, drive letters on Windows).