This library can be used in a variety of ways:
- Use
encode()ordecode()directly as an iterator. They will return slices of the output until the whole input string has been encoded or decoded. - Use
encode_alloc()ordecode_alloc(). It will always return a single slice allocated from the provided allocator, even if the output is identical to the input. - Use
encode_append()ordecode_append(). Instead of an allocator, you can pass a*std.ArrayList(u8)and the result will be appended to it. The input string must not be owned by the ArrayList. - Use
encode_maybe_append()ordecode_maybe_append(). Similar to*_append(), except the ArrayList won't be modified if the input and output are identical. The input string must not be owned by the ArrayList. Returns either the input string, or a slice from the ArrayList. The ArrayList does not need to be empty and won't be cleared before appending. - Use
std.fmt.Formatteraware APIs withfmtEncoded().
Encode_Options can specify which kinds of bytes are encoded independently for:
- ASCII alphabetical characters (
[A-Za-z]) - Decimal digits (
[0-9]) - spaces
- ASCII symbols
- C0 control characters and bytes >= 0x80
The default Encode_Options is conservative; it will encode application/x-www-form-urlencoded data according to HTML's rules, except that spaces will be encoded as %20 instead of +. Servers generally don't care if %20 or + is used, so this shouldn't be a problem, and it means it can also be used safely to escape URI data. Encoding spaces as + can be enabled explicitly if desired.
When decoding, + will be treated as a space by default, so make sure you turn this off explicitly if you're processing data where + is meant to be an unencoded literal +.
Consider using the standard library's std.Uri.Component.percentEncode when:
- You have a writer available
- You don't mind creating an
isValidCharhelper function to pass in - You don't need to encode spaces as
+
The standard library provides std.Uri.percentDecodeInPlace/std.Uri.percentDecodeBackwards however these require a preallocated mutable output buffer. Additionally, they do not support decoding + as a space.
It's highly unlikely that percent encoding/decoding will be a bottleneck for most applications, but some performance comparisons with the std implementations are provided in the benchmark.zig file and can be run with zig build benchmark. As with all microbenchmarks, take the results with several grains of salt.
Here are the results from my machine:
| Debug | Release | |
|---|---|---|
| percent_encoding.encode_append | 6.2 ns/B | 1.7 ns/B |
| percent_encoding.fmtEncoded | 7.8 ns/B | 1.9 ns/B |
| percent_encoding.encode_writer | 8.0 ns/B | 1.8 ns/B |
| std.Uri.Component.percentEncode | 12 ns/B | 2.4 ns/B |
| percent_encoding.decode_in_place | 7.7 ns/B | 0.84 ns/B |
| std.Uri.percentDecodeInPlace | 8.9 ns/B | 0.83 ns/B |