URL encoder/decoder · Guide
Percent Encoding Rust: Encoding URLs with percent-encoding and url
Rust has no URL encoding in the standard library. Two crates cover it: `percent-encoding` for raw control over which characters are escaped, and `url` for building whole URLs — and the second is usually the right answer.
The percent-encoding crate
You define an AsciiSet of characters to escape, which is more explicit than other languages and prevents the "which function encodes what" confusion:
use percent_encoding::{utf8_percent_encode, percent_decode_str, AsciiSet, NON_ALPHANUMERIC};
// RFC 3986 unreserved: keep A-Z a-z 0-9 - _ . ~
const COMPONENT: &AsciiSet = &NON_ALPHANUMERIC
.remove(b'-').remove(b'_').remove(b'.').remove(b'~');
let encoded = utf8_percent_encode("salt & pepper", COMPONENT).to_string();
// "salt%20%26%20pepper"
let decoded = percent_decode_str(&encoded).decode_utf8()?.to_string();Starting from NON_ALPHANUMERIC and removing the unreserved characters gives strict RFC 3986 encoding. The crate also ships predefined sets such as CONTROLS and QUERY for looser cases.
The url crate for whole URLs
For anything beyond a single value, url handles parsing, joining and query encoding, so you never assemble strings by hand:
use url::Url;
let mut url = Url::parse("https://example.com/search")?;
url.query_pairs_mut()
.append_pair("q", "salt & pepper")
.append_pair("page", "2");
// https://example.com/search?q=salt+%26+pepper&page=2Note query_pairs_mut uses form encoding, so a space becomes +. If you need %20, encode the value yourself with percent-encoding and set the query directly.
Decoding returns a Result
decode_utf8() returns a Result because the decoded bytes may not be valid UTF-8 — legacy Latin-1 escapes such as a lone %E9 are the usual cause.
Use decode_utf8_lossy() when you want replacement characters rather than an error, and reserve it for display. For anything you act on, handle the error — silently accepting malformed input is how parser-confusion bugs start.
Frequently asked questions
Which crate should I use?
url for building and parsing URLs; percent-encoding when you need control over exactly which characters are escaped.
Why is my space encoded as +?
query_pairs_mut uses form encoding. Encode with percent-encoding and set the query directly for %20.
Why does decoding return a Result?
Percent-decoded bytes are not guaranteed to be valid UTF-8, so the conversion can fail.
Ready to try it?
Open the free browser-based URL encoder/decoder and apply what you just read — no sign-up, runs locally.
Open the URL encoder/decoder tool