Something went wrong. Try again.
fork of gitlab.com/devnw/zig/uri for zig 0.17
Something went wrong. Try again.
Files
- Zig 98%
- Makefile 2%
README.md
URI #
RFC 3986 compliant URI/URL parsing and manipulation library for Zig.
Project Status: Active Development Current Version: v0.1.5 GitLab: devnw/zig/uri
Status #
| Aspect | Info |
|---|---|
| API Stability | Beta |
| Zig Version | 0.16.0+ |
| Platforms | Linux, macOS, Windows |
Features #
- RFC Compliant: Strict adherence to RFC 3986 (URI Generic Syntax) and RFC 8141 (URN)
- Minimal Dependencies: Core parsing uses only Zig standard library; optional
thread-pooldependency for parallel batch operations - Zero-Copy Parsing: No allocations for basic parsing operations
- Cross-Platform: Works on all Zig-supported targets
- Full Component Access: Scheme, authority, userinfo, host, port, path, query, fragment
- URI Resolution: RFC 3986 Section 5 reference resolution algorithm
- Normalization: Case, percent-encoding, path, and scheme-based normalization per RFC 3986 Section 6
- Percent-Encoding: Complete encode/decode support
- Parse Options: Strict/allow_spaces/iri_mode validation applied on input
- Component-Aware Encoding: Percent-encoding respects URI component rules
- URN Support: Full RFC 8141 URN parsing with NID, NSS, and r/q/f-components
- Resource Registry: Document storage with fetch callbacks and anchor support
Installation #
Add to your build.zig.zon:
.dependencies = .{
.uri = .{
.url = "https://gitlab.com/devnw/zig/uri/-/archive/main/uri-main.tar.gz",
.hash = "...",
},
},
Then in your build.zig:
const uri_dep = b.dependency("uri", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("uri", uri_dep.module("uri"));
Quick Start #
Parse a URI #
const uri = @import("uri");
pub fn main() !void {
const parsed = try uri.parse("https://user:pass@example.com:8080/path?query=value#fragment");
// Access components
std.debug.print("Scheme: {s}\n", .{parsed.scheme.?}); // "https"
std.debug.print("Host: {s}\n", .{parsed.host.?}); // "example.com"
std.debug.print("Port: {d}\n", .{parsed.port.?}); // 8080
std.debug.print("Path: {s}\n", .{parsed.path}); // "/path"
std.debug.print("Query: {s}\n", .{parsed.query.?}); // "query=value"
std.debug.print("Fragment: {s}\n", .{parsed.fragment.?}); // "fragment"
}
Parse a URN #
const parsed = try uri.parse("urn:isbn:0451450523");
std.debug.print("NID: {s}\n", .{parsed.urn.?.nid.?}); // "isbn"
std.debug.print("NSS: {s}\n", .{parsed.urn.?.nss.?}); // "0451450523"
Resolve URI References #
const allocator = std.heap.page_allocator;
const base = try uri.parse("http://example.com/a/b/c");
const reference = try uri.parse("../d");
const resolved = try uri.resolve(allocator, base, reference);
// Result: "http://example.com/a/d"
Percent-Encoding #
// Encode
const encoded = try uri.percentEncode(allocator, "hello world!", .path);
// Result: "hello%20world%21"
// Decode
const decoded = try uri.percentDecode(allocator, "hello%20world%21");
// Result: "hello world!"
Resource Registry #
var reg = uri.Registry.init(allocator);
defer reg.deinit();
try reg.register("https://example.com/schema.json", "{\"type\":\"object\"}", "application/json");
const resource = try reg.get("https://example.com/schema.json", false);
URI Components #
foo://user:pass@example.com:8042/over/there?name=ferret#nose
\_/ \________________________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| _________________|________________
/ \ / \
urn:example:animal:ferret:nose
The authority component breaks down into:
userinfo host port
+--+---+ +------+------+ +---+---+
user:pass@www.example.com:8080
Documentation #
- API Reference - Complete API documentation
- RFC Compliance - Detailed RFC compliance status
Roadmap #
v0.1.0 - Foundation ✅ #
Core URI parsing and manipulation functionality.
v0.2.0 - Enhanced Parsing #
Improved validation and encoding options.
v0.3.0 - IRI Support #
RFC 3987 Internationalized Resource Identifiers.
v0.4.0 - IPv6 Enhancements #
RFC 6874 IPv6 Zone ID support.
v1.0.0 - Stable Release #
Production-ready release.
RFC Compliance #
| RFC | Title | Status | Details |
|---|---|---|---|
| RFC 3986 | URI Generic Syntax | Implemented | #1, #2, #3 |
| RFC 8141 | URN Syntax | Implemented | #5 |
| RFC 3987 | IRI Syntax | Planned | #13, #14, #15 |
| RFC 6874 | IPv6 Zone ID | Planned | #16, #17, #18 |
| WHATWG | URL Standard | Partial | #19 |
See RFC_COMPLIANCE.md for detailed compliance information.
Building #
# Build
zig build
# Run tests
zig build test
# Run RFC test vectors
zig build test-vectors
# Run acceptance tests
zig build test-accept
# Run dataset tests (500+ URIs)
zig build test-dataset
# Run all tests
zig build test-all
Or use Make:
make # Build and test
make test # Run tests
make dev # Development workflow (fmt + check + test)
make help # Show all targets
Development #
With Nix #
nix develop
make dev
Requirements #
- Zig 0.16.0 or compatible
Cross-Platform Support #
The library supports all Zig target platforms:
- Linux (x86_64, ARM64, ARM, RISC-V)
- macOS (x86_64, ARM64)
- Windows (x86_64, ARM64)
- FreeBSD, NetBSD, OpenBSD
- And more...
License #
Apache-2.0 License - see LICENSE file.
Contributing #
Contributions are welcome! Please see our open issues for areas where help is needed.
Getting Started #
- Fork the repository
- Create a feature branch
- Make your changes
- Ensure all tests pass (
zig build test-all) - Submit a merge request
Guidelines #
- Code follows Zig style guidelines (
zig fmt) - All tests pass
- New features include tests
- RFC compliance is maintained
- Reference relevant issues in your MR
Priority Areas #
Related RFCs #
- RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax
- RFC 8141 - Uniform Resource Names (URNs)
- RFC 3987 - Internationalized Resource Identifiers (IRIs)
- RFC 6874 - Representing IPv6 Zone Identifiers in URIs
- WHATWG URL Standard - Living Standard for URLs