feat: add hurl! and local_folder! macros to make Url easier to create (#135)
* it was named `hurl!` instead of just `url!` because it was clashing with the crate `url` so we would have been forced to use it with `harmony_macros::url!` which is less sexy Reviewed-on: #135
This commit is contained in:
@@ -15,6 +15,7 @@ serde = "1.0.217"
|
||||
serde_yaml = "0.9.34"
|
||||
syn = "2.0.90"
|
||||
cidr.workspace = true
|
||||
url.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
|
||||
@@ -145,3 +145,71 @@ pub fn cidrv4(input: TokenStream) -> TokenStream {
|
||||
|
||||
panic!("Invalid IPv4 CIDR : {}", cidr_str);
|
||||
}
|
||||
|
||||
/// Creates a `harmony_types::net::Url::Url` from a string literal.
|
||||
///
|
||||
/// This macro parses the input string as a URL at compile time and will cause a
|
||||
/// compilation error if the string is not a valid URL.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use harmony_types::net::Url;
|
||||
/// use harmony_macros::hurl;
|
||||
///
|
||||
/// let url = hurl!("https://example.com/path");
|
||||
///
|
||||
/// let expected_url = url::Url::parse("https://example.com/path").unwrap();
|
||||
/// assert!(matches!(url, Url::Url(expected_url)));
|
||||
/// ```
|
||||
///
|
||||
/// The following example will fail to compile:
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// use harmony_macros::hurl;
|
||||
///
|
||||
/// // This is not a valid URL and will cause a compilation error.
|
||||
/// let _invalid = hurl!("not a valid url");
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn hurl(input: TokenStream) -> TokenStream {
|
||||
let input_lit = parse_macro_input!(input as LitStr);
|
||||
let url_str = input_lit.value();
|
||||
|
||||
match ::url::Url::parse(&url_str) {
|
||||
Ok(_) => {
|
||||
let expanded = quote! {
|
||||
::harmony_types::net::Url::Url(::url::Url::parse(#input_lit).unwrap())
|
||||
};
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
Err(e) => {
|
||||
let err_msg = format!("Invalid URL: {e}");
|
||||
syn::Error::new(input_lit.span(), err_msg)
|
||||
.to_compile_error()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a `harmony_types::net::Url::LocalFolder` from a string literal.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use harmony_types::net::Url;
|
||||
/// use harmony_macros::local_folder;
|
||||
///
|
||||
/// let local_path = local_folder!("/var/data/files");
|
||||
///
|
||||
/// let expected_path = String::from("/var/data/files");
|
||||
/// assert!(matches!(local_path, Url::LocalFolder(expected_path)));
|
||||
/// ```
|
||||
#[proc_macro]
|
||||
pub fn local_folder(input: TokenStream) -> TokenStream {
|
||||
let input_lit = parse_macro_input!(input as LitStr);
|
||||
let expanded = quote! {
|
||||
::harmony_types::net::Url::LocalFolder(#input_lit.to_string())
|
||||
};
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user