feat: add remote_url! and local_folder! macros to make Url easier to create
All checks were successful
Run Check Script / check (pull_request) Successful in 59s
All checks were successful
Run Check Script / check (pull_request) Successful in 59s
This commit is contained in:
parent
62fa3c2b10
commit
6119355681
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2389,6 +2389,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"syn 2.0.105",
|
"syn 2.0.105",
|
||||||
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -13,25 +13,25 @@ use harmony::{
|
|||||||
},
|
},
|
||||||
topology::K8sAnywhereTopology,
|
topology::K8sAnywhereTopology,
|
||||||
};
|
};
|
||||||
use harmony_types::net::Url;
|
use harmony_macros::remote_url;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let application = Arc::new(RustWebapp {
|
let application = Arc::new(RustWebapp {
|
||||||
name: "harmony-example-rust-webapp".to_string(),
|
name: "harmony-example-rust-webapp".to_string(),
|
||||||
domain: Url::Url(url::Url::parse("https://rustapp.harmony.example.com").unwrap()),
|
domain: remote_url!("https://rustapp.harmony.example.com"),
|
||||||
project_root: PathBuf::from("./webapp"), // Relative from 'harmony-path' param
|
project_root: PathBuf::from("./webapp"), // Relative from 'harmony-path' param
|
||||||
framework: Some(RustWebFramework::Leptos),
|
framework: Some(RustWebFramework::Leptos),
|
||||||
});
|
});
|
||||||
|
|
||||||
let discord_receiver = DiscordWebhook {
|
let discord_receiver = DiscordWebhook {
|
||||||
name: "test-discord".to_string(),
|
name: "test-discord".to_string(),
|
||||||
url: Url::Url(url::Url::parse("https://discord.doesnt.exist.com").unwrap()),
|
url: remote_url!("https://discord.doesnt.exist.com"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let webhook_receiver = WebhookReceiver {
|
let webhook_receiver = WebhookReceiver {
|
||||||
name: "sample-webhook-receiver".to_string(),
|
name: "sample-webhook-receiver".to_string(),
|
||||||
url: Url::Url(url::Url::parse("https://webhook-doesnt-exist.com").unwrap()),
|
url: remote_url!("https://webhook-doesnt-exist.com"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let app = ApplicationScore {
|
let app = ApplicationScore {
|
||||||
|
@ -15,6 +15,7 @@ serde = "1.0.217"
|
|||||||
serde_yaml = "0.9.34"
|
serde_yaml = "0.9.34"
|
||||||
syn = "2.0.90"
|
syn = "2.0.90"
|
||||||
cidr.workspace = true
|
cidr.workspace = true
|
||||||
|
url.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde = { version = "1.0.217", features = ["derive"] }
|
serde = { version = "1.0.217", features = ["derive"] }
|
||||||
|
@ -145,3 +145,71 @@ pub fn cidrv4(input: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
panic!("Invalid IPv4 CIDR : {}", cidr_str);
|
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::remote_url;
|
||||||
|
///
|
||||||
|
/// let remote_url = remote_url!("https://example.com/path");
|
||||||
|
///
|
||||||
|
/// let expected_url = url::Url::parse("https://example.com/path").unwrap();
|
||||||
|
/// assert!(matches!(remote_url, Url::Url(expected_url)));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The following example will fail to compile:
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// use harmony_macros::remote_url;
|
||||||
|
///
|
||||||
|
/// // This is not a valid URL and will cause a compilation error.
|
||||||
|
/// let _invalid = remote_url!("not a valid url");
|
||||||
|
/// ```
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn remote_url(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)
|
||||||
|
}
|
||||||
|
@ -51,6 +51,40 @@ impl TryFrom<String> for MacAddress {
|
|||||||
|
|
||||||
pub type IpAddress = std::net::IpAddr;
|
pub type IpAddress = std::net::IpAddr;
|
||||||
|
|
||||||
|
/// Represents a URL, which can either be a remote URL or a local file path.
|
||||||
|
///
|
||||||
|
/// For convenience, the `harmony_macros` crate provides `remote_url!` and `local_folder!`
|
||||||
|
/// macros to construct `Url` variants from string literals.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ### Manual Construction
|
||||||
|
///
|
||||||
|
/// The following example demonstrates how to build `Url` variants directly. This is
|
||||||
|
/// the standard approach if you are not using the `harmony_macros` crate.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// // The `use` statement below is for the doc test. In a real project,
|
||||||
|
/// // you would use `use harmony_types::Url;`
|
||||||
|
/// # use harmony_types::net::Url;
|
||||||
|
/// let remote_url = Url::Url(url::Url::parse("https://example.com").unwrap());
|
||||||
|
/// let local_path = Url::LocalFolder("/var/data".to_string());
|
||||||
|
///
|
||||||
|
/// assert!(matches!(remote_url, Url::Url(_)));
|
||||||
|
/// assert!(matches!(local_path, Url::LocalFolder(_)));
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ### Usage with `harmony_macros`
|
||||||
|
///
|
||||||
|
/// If `harmony_macros` is a dependency, you can create `Url`s more concisely.
|
||||||
|
///
|
||||||
|
/// ```rust,ignore
|
||||||
|
/// use harmony_macros::{remote_url, local_folder};
|
||||||
|
/// use harmony_types::Url;
|
||||||
|
///
|
||||||
|
/// let remote_url = remote_url!("https://example.com");
|
||||||
|
/// let local_path = local_folder!("/var/data");
|
||||||
|
/// ```
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Url {
|
pub enum Url {
|
||||||
LocalFolder(String),
|
LocalFolder(String),
|
||||||
|
Loading…
Reference in New Issue
Block a user