feat(alt): use macro to specify env var versioning instead

This commit is contained in:
samypr100 2025-09-22 18:04:15 -04:00
parent c42a037b07
commit 1427419b84
No known key found for this signature in database
GPG Key ID: E1717AA77760955D
4 changed files with 408 additions and 759 deletions

View File

@ -80,27 +80,31 @@ fn generate() -> String {
// Partition and sort environment variables into UV_ and external variables.
let (uv_vars, external_vars): (BTreeSet<_>, BTreeSet<_>) = EnvVars::metadata()
.iter()
.partition(|(var, _)| var.starts_with("UV_"));
.partition(|(var, _, _)| var.starts_with("UV_"));
output.push_str("uv defines and respects the following environment variables:\n\n");
for (var, doc) in uv_vars {
output.push_str(&render(var, doc));
for (var, doc, since) in uv_vars {
output.push_str(&render(var, doc, since));
}
output.push_str("\n\n## Externally defined variables\n\n");
output.push_str("uv also reads the following externally defined environment variables:\n\n");
for (var, doc) in external_vars {
output.push_str(&render(var, doc));
for (var, doc, since) in external_vars {
output.push_str(&render(var, doc, since));
}
output
}
/// Render an environment variable and its documentation.
fn render(var: &str, doc: &str) -> String {
fn render(var: &str, doc: &str, since: Option<&str>) -> String {
if let Some(since) = since {
format!("### `{var}`\n<small>Since `{since}`</small>\n\n{doc}\n\n")
} else {
format!("### `{var}`\n\n{doc}\n\n")
}
}
#[cfg(test)]

View File

@ -77,6 +77,14 @@ fn get_env_var_pattern_from_attr(attrs: &[Attribute]) -> Option<String> {
.map(|lit_str| lit_str.value())
}
fn get_since(attrs: &[Attribute]) -> Option<String> {
attrs
.iter()
.find(|a| a.path().is_ident("attr_since"))
.and_then(|attr| attr.parse_args::<LitStr>().ok())
.map(|lit_str| lit_str.value())
}
fn is_hidden(attrs: &[Attribute]) -> bool {
attrs.iter().any(|attr| attr.path().is_ident("attr_hidden"))
}
@ -93,13 +101,15 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To
ImplItem::Const(item) if !is_hidden(&item.attrs) => {
let name = item.ident.to_string();
let doc = get_doc_comment(&item.attrs);
Some((name, doc))
let since = get_since(&item.attrs);
Some((name, doc, since))
}
ImplItem::Fn(item) if !is_hidden(&item.attrs) => {
// Extract the environment variable patterns.
if let Some(pattern) = get_env_var_pattern_from_attr(&item.attrs) {
let doc = get_doc_comment(&item.attrs);
Some((pattern, doc))
let since = get_since(&item.attrs);
Some((pattern, doc, since))
} else {
None // Skip if pattern extraction fails.
}
@ -109,9 +119,11 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To
.collect();
let struct_name = &ast.self_ty;
let pairs = constants.iter().map(|(name, doc)| {
quote! {
(#name, #doc)
let pairs = constants.iter().map(|(name, doc, since)| {
if let Some(s) = since {
quote! { (#name, #doc, Some(#s)) }
} else {
quote! { (#name, #doc, None) }
}
});
@ -120,7 +132,7 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To
impl #struct_name {
/// Returns a list of pairs of env var and their documentation defined in this impl block.
pub fn metadata<'a>() -> &'a [(&'static str, &'static str)] {
pub fn metadata<'a>() -> &'a [(&'static str, &'static str, Option<&'static str>)] {
&[#(#pairs),*]
}
}
@ -138,3 +150,8 @@ pub fn attr_hidden(_attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn attr_env_var_pattern(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
#[proc_macro_attribute]
pub fn attr_since(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff