Skip to content

Commit 7f20bb7

Browse files
psteinroeclaude
andcommitted
fix: handle digit boundaries in snake_case conversion
convert_case splits on digit boundaries (e.g. "Md5" → "md_5") unlike the old biome_string_case behavior ("Md5" → "md5"). Add a to_snake_case helper that removes digit boundaries. Also fix clippy uninlined format args warning. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7344932 commit 7f20bb7

File tree

5 files changed

+24
-6
lines changed

5 files changed

+24
-6
lines changed

crates/pgls_workspace/src/workspace_types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn value_type(value: &Value) -> String {
103103
Value::Bool(true) => "true".to_string(),
104104
Value::Bool(false) => "false".to_string(),
105105
Value::Number(value) => format!("{}", value.as_f64().unwrap()),
106-
Value::String(value) => format!("\"{}\"", value),
106+
Value::String(value) => format!("\"{value}\""),
107107
Value::Array(_) => unimplemented!(),
108108
Value::Object(_) => unimplemented!(),
109109
}

xtask/codegen/src/generate_configuration.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{to_capitalized, update};
1+
use crate::{to_capitalized, to_snake_case, update};
22
use convert_case::{Case, Casing};
33
use pgls_analyse::{
44
GroupCategory, RegistryVisitor, RuleCategory, RuleGroup, RuleMeta, RuleMetadata,
@@ -608,7 +608,7 @@ fn generate_lint_group_struct(
608608
for (index, (rule, metadata)) in rules.iter().enumerate() {
609609
let summary = extract_summary_from_docs(metadata.docs);
610610
let rule_position = Literal::u8_unsuffixed(index as u8);
611-
let rule_identifier = quote::format_ident!("{}", rule.to_case(Case::Snake));
611+
let rule_identifier = quote::format_ident!("{}", to_snake_case(rule));
612612
let rule_name = Ident::new(&to_capitalized(rule), Span::call_site());
613613

614614
if metadata.recommended {
@@ -1119,7 +1119,7 @@ fn generate_action_group_struct(
11191119
for (index, (rule, metadata)) in rules.iter().enumerate() {
11201120
let summary = extract_summary_from_docs(metadata.docs);
11211121
let rule_position = Literal::u8_unsuffixed(index as u8);
1122-
let rule_identifier = quote::format_ident!("{}", rule.to_case(Case::Snake));
1122+
let rule_identifier = quote::format_ident!("{}", to_snake_case(rule));
11231123
let rule_name = Ident::new(&to_capitalized(rule), Span::call_site());
11241124

11251125
lines_rule.push(quote! {

xtask/codegen/src/generate_new_analyser_rule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub fn generate_new_analyser_rule(
115115
let file_name = format!(
116116
"{}/{}.rs",
117117
rule_folder.display(),
118-
rule_name.to_case(Case::Snake)
118+
crate::to_snake_case(&rule_name)
119119
);
120120
std::fs::write(file_name.clone(), code).unwrap_or_else(|_| panic!("To write {}", &file_name));
121121

xtask/codegen/src/generate_pglinter.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use anyhow::{Context, Result};
22
use convert_case::{Case, Casing};
3+
use crate::to_snake_case;
34
use quote::{format_ident, quote};
45
use regex::Regex;
56
use std::collections::BTreeMap;
@@ -88,7 +89,7 @@ fn parse_rules_sql(content: &str) -> Result<BTreeMap<String, PglinterRuleMeta>>
8889
// Parse fixes array
8990
let fixes: Vec<String> = parse_fixes_array(fixes_str);
9091

91-
let snake_name = name.to_case(Case::Snake);
92+
let snake_name = to_snake_case(&name);
9293
let camel_name = to_camel_case(&name);
9394

9495
let meta = PglinterRuleMeta {

xtask/codegen/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Codegen tools. Derived from Biome's codegen
22
3+
use convert_case::{Boundary, Case, Converter};
4+
35
mod generate_analyser;
46
mod generate_bindings;
57
mod generate_configuration;
@@ -48,6 +50,21 @@ pub fn update(path: &Path, contents: &str, mode: &Mode) -> Result<UpdateResult>
4850
Ok(UpdateResult::Updated)
4951
}
5052

53+
/// Convert to snake_case without splitting on digit boundaries.
54+
///
55+
/// `convert_case` treats digit-letter boundaries as word separators
56+
/// (e.g. "Md5" → "md_5"), but we want digits attached to the preceding
57+
/// word (e.g. "Md5" → "md5") to match the old biome_string_case behavior.
58+
pub fn to_snake_case(s: &str) -> String {
59+
Converter::new()
60+
.to_case(Case::Snake)
61+
.remove_boundary(Boundary::DigitUpper)
62+
.remove_boundary(Boundary::DigitLower)
63+
.remove_boundary(Boundary::UpperDigit)
64+
.remove_boundary(Boundary::LowerDigit)
65+
.convert(s)
66+
}
67+
5168
pub fn to_capitalized(s: &str) -> String {
5269
let mut c = s.chars();
5370
match c.next() {

0 commit comments

Comments
 (0)