Expand description
hostaddr
§Overview
hostaddr provides type-safe, validated types for working with network host identifiers:
Domain<S>– A validated DNS domain name, with IDNA/punycode and percent-encoding supportHost<S>– Either a domain name or an IP address (v4/v6)HostAddr<S>– A host with an optional port number (e.g.example.com:8080,[::1]:443)
All types are generic over their storage backend S, allowing you to choose the representation that best fits your use case – from zero-alloc stack buffers (Buffer) to shared smart pointers (Arc<str>).
§Features
no_stdandno-alloccompatible: Use theBuffertype for stack-allocated domains without any heap allocation- Generic storage: Works with
String,Arc<str>,Box<str>,Vec<u8>,SmolStr,Bytes, and more - IDNA/Punycode support: Automatic conversion of international domain names (e.g.
测试.中国to punycode) - Type-safe validation: Domain names are validated at construction time per RFC 1035 rules
- Percent-encoding: Transparent decoding of percent-encoded domains
- IPv4/IPv6: Full support for IP addresses, including proper
[::1]:portbracket syntax - Serde: Optional serialization/deserialization support
- Fuzzing: Built-in
arbitraryandquickcheckgenerators for property-based testing
§Installation
[dependencies]
hostaddr = "0.2"§Feature Flags
| Feature | Description |
|---|---|
std (default) | Standard library support, enables IDNA and percent-decoding |
alloc | Allocation support without std |
serde | Serialize/deserialize support |
arbitrary | Fuzzing with arbitrary crate |
cheap-clone | CheapClone trait for smart pointer types |
smol_str | SmolStr storage support |
bytes | Bytes storage support |
triomphe | triomphe::Arc storage support |
tinyvec | TinyVec storage support |
smallvec | SmallVec storage support |
§Quick Start
ⓘ
use hostaddr::HostAddr;
// Domain with port
let addr: HostAddr<String> = "example.com:8080".parse().unwrap();
assert!(addr.is_domain());
assert_eq!(addr.port(), Some(8080));
// IPv4 with port
let addr: HostAddr<String> = "127.0.0.1:3000".parse().unwrap();
assert!(addr.is_ipv4());
// IPv6 with port (bracket syntax)
let addr: HostAddr<String> = "[::1]:443".parse().unwrap();
assert!(addr.is_ipv6());
assert_eq!(addr.to_string(), "[::1]:443");
// International domain names (auto punycode)
let addr: HostAddr<String> = "测试.中国:80".parse().unwrap();§Examples
§Working with Domains
ⓘ
use hostaddr::Domain;
// Validated at construction -- invalid names are rejected
assert!(Domain::<String>::try_from("example.com").is_ok());
assert!(Domain::<String>::try_from("-invalid.com").is_err());
// International domain names are converted to punycode
let domain: Domain<String> = "测试.中国".parse().unwrap();
assert_eq!(domain.as_inner().as_str(), "xn--g6w251d.xn--fiqz9s");
// FQDN support
let domain: Domain<String> = "example.com.".parse().unwrap();
assert!(domain.is_fqdn());
// ASCII-only fast path (no punycode or percent-decoding)
let domain = Domain::try_from_ascii_str("example.com").unwrap();§Choosing a Storage Type
ⓘ
use hostaddr::HostAddr;
use std::sync::Arc;
// Heap-allocated String
let addr: HostAddr<String> = "example.com:8080".parse().unwrap();
// Shared ownership with Arc<str>
let addr: HostAddr<Arc<str>> = "example.com:8080".parse().unwrap();
// Byte storage
let addr: HostAddr<Vec<u8>> = "example.com".parse().unwrap();§Stack-Allocated Domains (no_std / no-alloc)
ⓘ
use hostaddr::{HostAddr, Buffer, Domain};
// No heap allocation -- 255-byte stack buffer
let domain: Domain<Buffer> = Domain::try_from("example.com").unwrap();
let addr: HostAddr<Buffer> = HostAddr::try_from("example.com:443").unwrap();§Manipulating Addresses
ⓘ
use hostaddr::HostAddr;
let mut addr: HostAddr<String> = "example.com".parse().unwrap();
addr.set_port(8080);
assert_eq!(addr.to_string(), "example.com:8080");
// Builder-style with default port
let addr = "example.com".parse::<HostAddr<String>>().unwrap()
.with_default_port(443);
assert_eq!(addr.port(), Some(443));§Verification Functions
ⓘ
use hostaddr::{verify_domain, verify_ascii_domain};
assert!(verify_domain(b"example.com").is_ok());
assert!(verify_domain("测试.中国".as_bytes()).is_ok());
assert!(verify_ascii_domain(b"example.com").is_ok());
assert!(verify_ascii_domain("测试.中国".as_bytes()).is_err());§License
hostaddr is under the terms of both the MIT license and the
Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT for details.
Copyright (c) 2025 Al Liu.
Structs§
- Buffer
- An immutable buffer which contains a valid domain.
- Domain
- A DNS domain name, as
.dot-separated labels. Non-ASCII labels are encoded in punycode per IDNA if this is the host of a special URL, or percent encoded for non-special URLs. - Host
Addr - A host address, which consists of a
Hostand an optional port number. - Parse
Ascii Domain Error - The provided input could not be parsed because it is not an ASCII syntactically-valid DNS Domain.
- Parse
Ascii Host Error - An error which can be returned when parsing an ASCII
Host. - Parse
Domain Error - The provided input could not be parsed because it is not a syntactically-valid DNS Domain.
- Parse
Host Error - An error which can be returned when parsing a
Host. - TryUnwrap
Error - Error returned by the derived
TryUnwrapimplementation.
Enums§
- Host
- The host name
- Parse
Ascii Host Addr Error - An error which can be returned when parsing a
HostAddr. - Parse
Host Addr Error - An error which can be returned when parsing a
HostAddr.
Functions§
- verify_
ascii_ domain - Verifies that the input is a valid ASCII domain name.
- verify_
ascii_ domain_ allow_ percent_ encoding - Verifies that the input is a valid ASCII domain name. The input can be a percent-encoded domain name.
- verify_
domain allocorstd - Verifies that the input is a valid domain name.