handles_utils/validator.rs
1//! # Handle Validator
2//!
3//! `handle_validator` provides a `HandleValidator` struct to determine the validity of a given
4//! user handle.
5
6// We need the ALLOWED_UNICODE_CHARACTER_RANGES for the build
7#[path = "../constants.rs"]
8mod constants;
9use constants::ALLOWED_UNICODE_CHARACTER_RANGES;
10
11/// Reserved words that cannot be used as the handle.
12const RESERVED_WORDS: [&str; 8] =
13 ["adm1n", "every0ne", "a11", "adm1n1strat0r", "m0d", "m0derat0r", "here", "channe1"];
14
15// We MUST have the RESERVED_WORDS constant as canonical.
16// Cannot easily be canonicalized at compile time currently
17#[test]
18fn ensure_reserved_words_canonical() {
19 for &word in &RESERVED_WORDS {
20 let canonical = crate::convert_to_canonical(word);
21 assert_eq!(
22 word, canonical,
23 "The reserved word '{}' MUST match canonical form: '{}'",
24 word, canonical
25 );
26 }
27}
28
29/// Characters that cannot be used in the handle.
30const BLOCKED_CHARACTERS: [char; 17] =
31 ['"', '#', '%', '(', ')', ',', '.', '/', ':', ';', '<', '>', '@', '\\', '`', '{', '}'];
32
33// We MUST have the BLOCKED_CHARACTERS constant sorted or we cannot use the faster `binary_search` function.
34// Cannot easily be sorted at compile time currently
35#[test]
36fn ensure_sorted_blocked_characters() {
37 let mut sorted = BLOCKED_CHARACTERS;
38 sorted.sort();
39 assert_eq!(BLOCKED_CHARACTERS, sorted);
40}
41
42/// Determines whether a given canonicalized string is a reserved handle in the current context.
43///
44/// # Arguments
45///
46/// * `input_str` - A string slice representing the canonicalized handle to check.
47///
48/// # Returns
49///
50/// A boolean value indicating whether the string is a reserved handle (`true`) or not (`false`).
51pub fn is_reserved_canonical_handle(input_str: &str) -> bool {
52 RESERVED_WORDS.contains(&input_str)
53}
54
55/// Checks if the given string contains any blocked characters.
56///
57/// # Arguments
58///
59/// * `input_str` - A string slice to check for blocked characters.\
60///
61/// # Returns
62///
63/// A boolean value indicating whether the string contains any blocked characters (`true`) or not (`false`).
64pub fn contains_blocked_characters(input_str: &str) -> bool {
65 input_str.chars().any(|c| BLOCKED_CHARACTERS.binary_search(&c).is_ok())
66}
67
68/// Checks that the given string contains characters within the ranges of supported
69/// unicode character sets.
70///
71/// # Arguments
72///
73/// * `input_str` - A string slice to check for characters within the allowed unicode character sets..
74///
75/// # Returns
76///
77/// A boolean value indicating whether the string contains characters within the allowed unicode character sets (`true`) or not (`false`).
78pub fn consists_of_supported_unicode_character_sets(input_str: &str) -> bool {
79 input_str
80 .chars()
81 .all(|c| ALLOWED_UNICODE_CHARACTER_RANGES.iter().any(|range| range.contains(&(c as u16))))
82}