Crate links_domainmap

Source
Expand description

A map with domain name keys, with support for wildcards

A DomainMap<T> holds “[reference identifiers]” (domain names possibly with wildcards) as Domains. A DomainMap can be indexed using a Domain, which stores either a “reference identifier” (for matching methods, e.g. get or get_mut) or a “presented identifier” (for equality-comparing methods, e.g. get_eq or remove).

§Cargo features

  • serde: Enable serde serialization and deserialization for DomainMap and Domain

§Example usage

use links_domainmap::{Domain, DomainMap};

// Create a new `DomainMap` with `u32` values
let mut domainmap = DomainMap::<u32>::new(); // or `with_capacity()`

// Set a value for `example.com`
domainmap.set(Domain::presented("example.com")?, 5);

// Set a value for the wildcard domain `*.example.net`
domainmap.set(Domain::presented("*.example.net")?, 100);

// Get the value for the domain matching `example.com`
assert_eq!(domainmap.get(&Domain::reference("example.com")?), Some(&5));

// Get the value for the domain matching `foo.example.net`
assert_eq!(
	domainmap.get(&Domain::reference("foo.example.net")?),
	Some(&100)
);

// Get the value for the domain `*.example.net` (using `==` internally)
assert_eq!(
	domainmap.get_eq(&Domain::presented("*.example.net")?),
	Some(&100)
);

// Try to get the value for the domain matching `a.b.c.example.net`
assert_eq!(
	domainmap.get(&Domain::reference("a.b.c.example.net")?),
	None // Wildcards only work for one label
);

// Update the value for `example.com`
let old_value = domainmap.set(Domain::presented("example.com")?, 50);
assert_eq!(old_value, Some(5));

// Modify the value for the domain matching `foo.example.net`
let val = domainmap.get_mut(&Domain::reference("foo.example.net")?);
if let Some(val) = val {
	*val += 1;
	assert_eq!(val, &101);
}

// Set a value for `www.example.net`, overriding the wildcard `*.example.net`
domainmap.set(Domain::presented("www.example.net")?, 250);

// The wildcard still exists, but is overridden for `www.example.net`
assert_eq!(
	domainmap.get(&Domain::reference("www.example.net")?),
	Some(&250)
);
assert_eq!(
	domainmap.get(&Domain::reference("other.example.net")?),
	Some(&101)
);

// Remove the entry for `example.com`
let old_value = domainmap.remove(&Domain::presented("example.com")?);
assert_eq!(old_value, Some(50));
assert_eq!(
	domainmap.get(&Domain::reference("example.com")?),
	None // Not in the map anymore
);

// Show the amount of key-value pairs in the map
assert_eq!(domainmap.len(), 2); // `*.example.net` and `www.example.net`

// Clear the map
domainmap.clear();
assert!(domainmap.is_empty());

§Domain name syntax

Rules for domain names as implemented here (based on a mix of RFC 952, RFC 1034, RFC 1123, RFC 2181, the WHATWG URL specification, browser implementations, and browser bugs) are:

  • A domain name has a maximum total length (including ’.’s) of 253 characters/octets/bytes (RFC 1034 section 3.1, Unicode TR46 section 4)
  • Domain name labels (the things seperated by ‘.’) have a maximum length of 63 characters/octets/bytes each, not including the separators (RFC 1034 section 3.5, RFC 1123 section 2.1, RFC 2181 section 11)
  • A domain name label must consist of only ASCII letters ('a'..='z' | 'A'..='Z'), digits ('0'..='9'), and hyphens ('-'). A label can not start or end with a hyphen. (RFC 952 section B, RFC 1034 section 3.5, RFC 1123 section 2.1)
  • Additionally, a label can also contain underscores ('_') in the same places as letters for compatibility reasons. (Additional discussion around underscores in a Firefox bug, implementations in Chromium and Firefox)
  • A wildcard ("*") can only comprise the entire left-most label of a domain name and matches exactly one label. ([RFC 2818] section 3.1, RFC 6125 section 6.4.3; i.e. "*.example.com" is valid and matches "foo.example.com" and "bar.example.com" but does not match "foo.bar.example.com" or "example.com", and all of the following are invalid: "*.*.example.com", "foo.*.example.com", "fo*.example.com", "*oo.example.com", "f*o.example.com")
  • No special treatment is given to wildcards on top-level domains (e.g. "*.com"), or on other public suffixes (e.g. “*.co.uk” or "*.pvt.k12.ma.us"), which allows some potentially invalid wildcard domains; full wildcard domains ("*") are not allowed
  • Percent-encoded domain names (e.g. "e%78ample.com") are not supported, and '%' is treated as an invalid character

Modules§

domain 🔒
Types for domain names, either as a reference identifier or a presented identifier, with support for internationalized domain names
map 🔒
A map with domain name keys, with support for wildcards
serde 🔒
Serialization and deserialization implementations using serde for DomainMap and Domain

Structs§

Domain
A domain name split into individual labels (not including the root label).
DomainMap
A map with domain name keys, with support for wildcards
Label
A domain name label, stored in lowercase in its ASCII-encoded form

Enums§

ParseError
An error encountered while parsing a domain name