Skip to content

Instantly share code, notes, and snippets.

@daltonclaybrook
Created June 23, 2022 16:36
Show Gist options
  • Save daltonclaybrook/37307dfd3c16fe49beb9be288fa96deb to your computer and use it in GitHub Desktop.
Save daltonclaybrook/37307dfd3c16fe49beb9be288fa96deb to your computer and use it in GitHub Desktop.
Example of compile-time URL parsing in Rust
extern crate proc_macro;
use proc_macro::TokenStream;
use syn::parse_macro_input;
use quote::quote;
use regex::Regex;
#[proc_macro]
pub fn make_url(_item: TokenStream) -> TokenStream {
let input = parse_macro_input!(_item as syn::LitStr);
let url_regex = Regex::new(r"^(\w+)://([\w-]+(?:\.[\w-]+)*)((?:/[\w-]+)*)?(\?[\w\-=&]+)?$").unwrap();
let value = input.value();
let captures = url_regex.captures(&value).expect("The string literal is not a valid URL");
let scheme = captures.get(1).expect("Could not determine scheme").as_str();
let domain = captures.get(2).expect("Could not determine domain").as_str();
let path = captures.get(3).expect("Could not determine path").as_str();
let query = captures.get(4).map_or("", |m| m.as_str());
let path = if path.is_empty() { "/" } else { path };
quote! {
URL {
scheme: #scheme,
domain: #domain,
path: #path,
query: #query,
}
}.into()
}
#[macro_use]
extern crate url_macros;
pub struct URL {
pub scheme: &'static str,
pub domain: &'static str,
pub path: &'static str,
pub query: &'static str,
}
fn main() {
let apple_url: URL = make_url!("http://apple.com?foo=bar&fizz=buzz");
let invalid_url: URL = make_url!("foobar");
println!("Scheme: {}", apple_url.scheme);
println!("Domain: {}", apple_url.domain);
println!("Path: {}", apple_url.path);
println!("Query: {}", apple_url.query);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment