Refactor and document nick module

This commit is contained in:
Joscha 2024-12-05 14:01:55 +01:00
parent 92ea7f0aa0
commit 096df5d9fa
3 changed files with 13 additions and 7 deletions

View file

@ -4,9 +4,11 @@ version = "0.6.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
caseless = "0.2.1"
jiff = { version = "0.1.15", default-features = false, features = ["std"] } jiff = { version = "0.1.15", default-features = false, features = ["std"] }
serde = { version = "1.0.215", features = ["derive"] } serde = { version = "1.0.215", features = ["derive"] }
serde_json = "1.0.133" serde_json = "1.0.133"
unicode-normalization = "0.1.24"
[lints] [lints]
rust.unsafe_code = { level = "forbid", priority = 1 } rust.unsafe_code = { level = "forbid", priority = 1 }

View file

@ -1,4 +1,5 @@
pub mod api; pub mod api;
mod emoji; mod emoji;
pub mod nick;
pub use crate::emoji::Emoji; pub use crate::emoji::Emoji;

View file

@ -81,17 +81,18 @@ pub fn hue(emoji: &Emoji, nick: &str) -> u8 {
/// 1. Apply [`mention`] /// 1. Apply [`mention`]
/// 2. Convert to NFKC /// 2. Convert to NFKC
/// 3. Case fold /// 3. Case fold
/// 4. Convert to NFC
/// ///
/// Steps 2 and 3 are meant to be an alternative to the NKFC_Casefold derived /// Steps 2 to 4 are meant to emulate NKFC_Casefold, but may differ in some edge
/// property that's easier to implement, even though it may be incorrect in some /// cases. Most notably, they don't ignore default ignorable code points. Maybe
/// edge cases. /// there are also other edge cases I don't know about.
///
/// [0]: https://github.com/CylonicRaider/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/stores/chat.js#L14
pub fn normalize(nick: &str) -> String { pub fn normalize(nick: &str) -> String {
mention(nick) // Step 1 mention(nick) // Step 1
.nfkc() // Step 2 .nfkc() // Step 2
.default_case_fold() // Step 3 .default_case_fold() // Step 3
.collect() .collect::<String>()
.nfc() // Step 4
.collect::<String>()
} }
fn is_non_whitespace_delimiter(c: char) -> bool { fn is_non_whitespace_delimiter(c: char) -> bool {
@ -108,12 +109,14 @@ fn is_non_whitespace_delimiter(c: char) -> bool {
/// highlight as a mention in the official euphoria client. It should ping any /// highlight as a mention in the official euphoria client. It should ping any
/// people using the original nick. It might also ping other people. /// people using the original nick. It might also ping other people.
/// ///
/// In the official euphoria client, mentions are non-whitespace characters /// [In the official euphoria client][0], mentions are non-whitespace characters
/// delimited by whitespace and any of the following characters: /// delimited by whitespace and any of the following characters:
/// ///
/// `,`, `.`, `!`, `?`, `;`, `&`, `<`, `>`, `'`, `"`. /// `,`, `.`, `!`, `?`, `;`, `&`, `<`, `>`, `'`, `"`.
/// ///
/// The first character of a mention may be a delimiting character. /// The first character of a mention may be a delimiting character.
///
/// [0]: https://github.com/CylonicRaider/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/stores/chat.js#L14
pub fn mention(nick: &str) -> String { pub fn mention(nick: &str) -> String {
let mut nick = nick.chars().filter(|c| !c.is_whitespace()); let mut nick = nick.chars().filter(|c| !c.is_whitespace());
let mut result = String::new(); let mut result = String::new();