1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
#[cfg(feature = "alloc")] use alloc::vec::Vec; /// Converts the given slice to its ASCII title case equivalent in-place. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z' in the first byte; /// subsequent bytes with ASCII letters 'A' to 'Z' are mapped to 'a' to 'z'; /// non-ASCII letters are unchanged. /// /// This function can be used to implement [`String#capitalize!`] for ASCII /// strings in Ruby. /// /// To return a new titlecased value without modifying the existing one, use /// [`to_ascii_titlecase`]. /// /// # Examples /// /// ``` /// # use roe::make_ascii_titlecase; /// let mut buf = *b"ABCxyz"; /// make_ascii_titlecase(&mut buf); /// assert_eq!(buf, *b"Abcxyz"); /// /// let mut buf = *b"1234%&*"; /// make_ascii_titlecase(&mut buf); /// assert_eq!(buf, *b"1234%&*"); /// /// let mut buf = *b"ABC1234%&*"; /// make_ascii_titlecase(&mut buf); /// assert_eq!(buf, *b"Abc1234%&*"); /// /// let mut buf = *b"1234%&*abcXYZ"; /// make_ascii_titlecase(&mut buf); /// assert_eq!(buf, *b"1234%&*abcxyz"); /// /// let mut buf = *b"ABC, XYZ"; /// make_ascii_titlecase(&mut buf); /// assert_eq!(buf, *b"Abc, xyz"); /// ``` /// /// [`String#capitalize!`]: https://ruby-doc.org/core-2.6.3/String.html#method-i-capitalize-21 #[inline] #[allow(clippy::module_name_repetitions)] pub fn make_ascii_titlecase<T: AsMut<[u8]>>(slice: &mut T) { let slice = slice.as_mut(); if let Some((head, tail)) = slice.split_first_mut() { head.make_ascii_uppercase(); tail.make_ascii_lowercase(); } } /// Returns a vector containing a copy of the given slice where each byte is /// mapped to its ASCII title case equivalent. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z' in the first byte; /// subsequent bytes with ASCII letters 'A' to 'Z' are mapped to 'a' to 'z'; /// non-ASCII letters are unchanged. /// /// This function can be used to implement [`String#capitalize`] and /// [`Symbol#capitalize`] for ASCII strings in Ruby. /// /// To titlecase the value in-place, use [`make_ascii_titlecase`]. /// /// # Examples /// /// ``` /// # use roe::to_ascii_titlecase; /// assert_eq!(to_ascii_titlecase("ABCxyz"), &b"Abcxyz"[..]); /// assert_eq!(to_ascii_titlecase("1234%&*"), &b"1234%&*"[..]); /// assert_eq!(to_ascii_titlecase("ABC1234%&*"), &b"Abc1234%&*"[..]); /// assert_eq!(to_ascii_titlecase("1234%&*abcXYZ"), &b"1234%&*abcxyz"[..]); /// assert_eq!(to_ascii_titlecase("ABC, XYZ"), &b"Abc, xyz"[..]); /// ``` /// /// [`String#capitalize`]: https://ruby-doc.org/core-2.6.3/String.html#method-i-capitalize /// [`Symbol#capitalize`]: https://ruby-doc.org/core-2.6.3/Symbol.html#method-i-capitalize #[inline] #[cfg(feature = "alloc")] #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] #[allow(clippy::module_name_repetitions)] pub fn to_ascii_titlecase<T: AsRef<[u8]>>(slice: T) -> Vec<u8> { let slice = slice.as_ref(); let mut titlecase = slice.to_ascii_lowercase(); if let Some(head) = titlecase.first_mut() { head.make_ascii_uppercase(); } titlecase } #[cfg(test)] mod tests { #[test] fn make_ascii_titlecase_empty() { let mut buf = *b""; super::make_ascii_titlecase(&mut buf); assert_eq!(buf, *b""); } #[test] #[cfg(feature = "alloc")] fn to_ascii_titlecase_empty() { assert_eq!(super::to_ascii_titlecase(""), b""); } }