add util for camel to snake case conversion

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2024-07-23 07:03:33 +00:00
parent 91b49a7786
commit 5c0bf29122
2 changed files with 52 additions and 1 deletions

View file

@ -1,4 +1,4 @@
use crate::Result;
use crate::{utils::exchange, Result};
pub const EMPTY: &str = "";
@ -26,6 +26,41 @@ macro_rules! is_format {
};
}
#[inline]
#[must_use]
pub fn camel_to_snake_string(s: &str) -> String {
let est_len = s
.chars()
.fold(s.len(), |est, c| est.saturating_add(usize::from(c.is_ascii_uppercase())));
let mut ret = String::with_capacity(est_len);
camel_to_snake_case(&mut ret, s.as_bytes()).expect("string-to-string stream error");
ret
}
#[inline]
pub fn camel_to_snake_case<I, O>(output: &mut O, input: I) -> Result<()>
where
I: std::io::Read,
O: std::fmt::Write,
{
let mut state = false;
input
.bytes()
.take_while(Result::is_ok)
.map(Result::unwrap)
.map(char::from)
.try_for_each(|ch| {
let m = ch.is_ascii_uppercase();
let s = exchange(&mut state, !m);
if m && s {
output.write_char('_')?;
}
output.write_char(ch.to_ascii_lowercase())?;
Result::<()>::Ok(())
})
}
/// Find the common prefix from a collection of strings and return a slice
/// ```
/// use conduit_core::utils::string::common_prefix;

View file

@ -134,3 +134,19 @@ async fn mutex_map_contend() {
tokio::try_join!(join_b, join_a).expect("joined");
assert!(map.is_empty(), "Must be empty");
}
#[test]
fn camel_to_snake_case_0() {
use utils::string::camel_to_snake_string;
let res = camel_to_snake_string("CamelToSnakeCase");
assert_eq!(res, "camel_to_snake_case");
}
#[test]
fn camel_to_snake_case_1() {
use utils::string::camel_to_snake_string;
let res = camel_to_snake_string("CAmelTOSnakeCase");
assert_eq!(res, "camel_tosnake_case");
}