#unicode #title-case #lower-case #locale #tr #turkish #az #azeri

unicode_titlecase

A crate to add Unicode titlecase and Turkish and Azeri locale upper/lowercase utilities to chars and strings

12 stable releases

Uses new Rust 2024

2.5.0 Dec 13, 2025
2.4.0 Sep 25, 2024
2.3.0 Sep 21, 2023
2.2.1 Aug 12, 2023
1.1.0 May 27, 2022

#166 in Text processing

Download history 111/week @ 2025-11-04 273/week @ 2025-11-11 246/week @ 2025-11-18 190/week @ 2025-11-25 20/week @ 2025-12-02 47/week @ 2025-12-09 144/week @ 2025-12-16 57/week @ 2025-12-23 12/week @ 2025-12-30 54/week @ 2026-01-06 150/week @ 2026-01-13 221/week @ 2026-01-20 372/week @ 2026-01-27 432/week @ 2026-02-03 384/week @ 2026-02-10 346/week @ 2026-02-17

1,570 downloads per month
Used in 4 crates (3 directly)

MIT/Apache

110KB
2K SLoC

Unicode Titlecase

Unicode titlecasing operations for chars and strings. The crate supports additional functionality for the TR/AZ locales.

GitHub Workflow Status docs.rs Crates.io Crates.io

Usage

Chars

To turn a char into its titlecase equivalent [char; 3]array:

use unicode_titlecase::to_titlecase;

assert_eq!(to_titlecase('A'), ['A', '\0', '\0']);
assert_eq!(to_titlecase('DŽ'), ['Dž', '\0', '\0']);
assert_eq!(to_titlecase(''), ['F', 'f', 'l']);

Or use the iterator version that follows the same format as the std library. The crate defines a Trait that is implemented on char:

use unicode_titlecase::TitleCase;
assert_eq!('i'.to_titlecase().to_string(), "I");
assert_eq!('A'.to_titlecase().to_string(), "A");
assert_eq!('DŽ'.to_titlecase().to_string(), "Dž");
assert_eq!(''.to_titlecase().to_string(), "Ffl");

Strings

A similar trait is defined on str. This will titlecase the first char of the string, leave the rest unchanged, and return a newly allocated String.

use unicode_titlecase::StrTitleCase;
assert_eq!("iii".to_titlecase(), "Iii");
assert_eq!("ABC".to_titlecase(), "ABC");
assert_eq!("DŽDŽ".to_titlecase(), "DžDŽ");
assert_eq!("fflabc".to_titlecase(), "Fflabc");

Alternatively, you could lowercase the rest of the str:

use unicode_titlecase::StrTitleCase;
assert_eq!("iIi".to_titlecase_lower_rest(), "Iii");
assert_eq!("ABC".to_titlecase_lower_rest(), "Abc");
assert_eq!("DŽDŽ".to_titlecase_lower_rest(), "Dždž");
assert_eq!("fflabc".to_titlecase_lower_rest(), "Fflabc");

Testing a char or str

To see if the char is already titlecase, is_titlecase is provided:

use unicode_titlecase::TitleCase;
assert!('A'.is_titlecase());
assert!('Dž'.is_titlecase());
assert!('İ'.is_titlecase());

assert!(!'a'.is_titlecase());
assert!(!'DŽ'.is_titlecase());
assert!(!''.is_titlecase());

To test if a str is already titlecase, two options are provided. The first, starts_titlecase returns true if the first character is titlecased--ignoring the rest of the str. The second starts_titlecase_rest_lower only returns true if the first char is titlecase and the rest of the str is lowercase.

use unicode_titlecase::StrTitleCase;
assert!("Abc".starts_titlecase());
assert!("ABC".starts_titlecase());
assert!(!"abc".starts_titlecase());

assert!("Abc".starts_titlecase_rest_lower());
assert!("İbc".starts_titlecase_rest_lower());
assert!(!"abc".starts_titlecase_rest_lower());
assert!(!"ABC".starts_titlecase_rest_lower());
assert!(!"İİ".starts_titlecase_rest_lower());

All testing functions work the same regardless of locale.

Locale

The Turkish and Azeri (TR/AZ) locales have different rules for how to titlecase certain characters. The to_titlecase functions assume the locale is neither of these locations. A tr_or_az version of each function is provided instead.

use unicode_titlecase::{to_titlecase_tr_or_az, StrTitleCase, TitleCase};
assert_eq!(to_titlecase_tr_or_az('i'), ['İ', '\0', '\0']);
assert_eq!('i'.to_titlecase_tr_or_az().to_string(), "İ");
assert_eq!("iIi".to_titlecase_tr_or_az(), "İIi");
assert_eq!("iIi".to_titlecase_tr_or_az_lower_rest(), "İıi");

Additionally, there are upper and lower case utilities for the Turkish and Azeri located in the tr_az module.

use unicode_titlecase::tr_az::{to_uppercase_tr_or_az, to_lowercase_tr_or_az, StrTrAzCasing};
assert_eq!(to_uppercase_tr_or_az('i').to_string(), "İ");
assert_eq!(to_lowercase_tr_or_az('I'), 'ı');
assert_eq!("İIAb".to_lowercase_tr_az(), "iıab");
assert_eq!("iıab".to_uppercase_tr_az(), "İIAB");

License

Licensed under either of

at your option.

Changelog

  • 12 December 2025 - Release 2.5.0:
    • Upgraded to Unicode 17.0.0,
    • Upgraded to Rust 2024 edition,
    • Started a changelog

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

No runtime deps