2019-03-10 17:19:47 +00:00
|
|
|
/// Returns the index of the character after the first camel-case component of `s`.
|
2019-09-18 06:37:41 +00:00
|
|
|
#[must_use]
|
2018-10-11 22:36:40 +00:00
|
|
|
pub fn until(s: &str) -> usize {
|
2018-08-29 02:32:20 +00:00
|
|
|
let mut iter = s.char_indices();
|
|
|
|
if let Some((_, first)) = iter.next() {
|
|
|
|
if !first.is_uppercase() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
let mut up = true;
|
|
|
|
let mut last_i = 0;
|
|
|
|
for (i, c) in iter {
|
|
|
|
if up {
|
|
|
|
if c.is_lowercase() {
|
|
|
|
up = false;
|
|
|
|
} else {
|
|
|
|
return last_i;
|
|
|
|
}
|
|
|
|
} else if c.is_uppercase() {
|
|
|
|
up = true;
|
|
|
|
last_i = i;
|
|
|
|
} else if !c.is_lowercase() {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
2021-03-12 14:30:50 +00:00
|
|
|
if up { last_i } else { s.len() }
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
2019-01-31 01:15:29 +00:00
|
|
|
/// Returns index of the last camel-case component of `s`.
|
2019-09-18 06:37:41 +00:00
|
|
|
#[must_use]
|
2018-10-11 22:36:40 +00:00
|
|
|
pub fn from(s: &str) -> usize {
|
2018-08-29 02:32:20 +00:00
|
|
|
let mut iter = s.char_indices().rev();
|
|
|
|
if let Some((_, first)) = iter.next() {
|
|
|
|
if !first.is_lowercase() {
|
|
|
|
return s.len();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return s.len();
|
|
|
|
}
|
|
|
|
let mut down = true;
|
|
|
|
let mut last_i = s.len();
|
|
|
|
for (i, c) in iter {
|
|
|
|
if down {
|
|
|
|
if c.is_uppercase() {
|
|
|
|
down = false;
|
|
|
|
last_i = i;
|
|
|
|
} else if !c.is_lowercase() {
|
|
|
|
return last_i;
|
|
|
|
}
|
|
|
|
} else if c.is_lowercase() {
|
|
|
|
down = true;
|
2021-02-25 10:25:22 +00:00
|
|
|
} else if c.is_uppercase() {
|
|
|
|
last_i = i;
|
2018-08-29 02:32:20 +00:00
|
|
|
} else {
|
|
|
|
return last_i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
last_i
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2018-10-11 22:36:40 +00:00
|
|
|
use super::{from, until};
|
2018-08-29 02:32:20 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn from_full() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(from("AbcDef"), 0);
|
|
|
|
assert_eq!(from("Abc"), 0);
|
2021-02-25 10:25:22 +00:00
|
|
|
assert_eq!(from("ABcd"), 0);
|
|
|
|
assert_eq!(from("ABcdEf"), 0);
|
|
|
|
assert_eq!(from("AabABcd"), 0);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn from_partial() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(from("abcDef"), 3);
|
|
|
|
assert_eq!(from("aDbc"), 1);
|
2021-02-25 10:25:22 +00:00
|
|
|
assert_eq!(from("aabABcd"), 3);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn from_not() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(from("AbcDef_"), 7);
|
|
|
|
assert_eq!(from("AbcDD"), 5);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn from_caps() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(from("ABCD"), 4);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn until_full() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(until("AbcDef"), 6);
|
|
|
|
assert_eq!(until("Abc"), 3);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn until_not() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(until("abcDef"), 0);
|
|
|
|
assert_eq!(until("aDbc"), 0);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn until_partial() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(until("AbcDef_"), 6);
|
|
|
|
assert_eq!(until("CallTypeC"), 8);
|
|
|
|
assert_eq!(until("AbcDD"), 3);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn until_caps() {
|
2018-10-11 22:36:40 +00:00
|
|
|
assert_eq!(until("ABCD"), 0);
|
2018-08-29 02:32:20 +00:00
|
|
|
}
|
2018-10-11 22:36:40 +00:00
|
|
|
}
|