Skip to main content

emoji_sanitize/
lib.rs

1//! # emoji-sanitize
2//!
3//! Strip Unicode characters that emoji rendering uses but plain-text
4//! analysis doesn't need: variation selectors (U+FE00–U+FE0F),
5//! the zero-width joiner (U+200D), and skin-tone modifiers
6//! (U+1F3FB–U+1F3FF).
7//!
8//! Two modes:
9//! - [`strip_modifiers`] — keep the base emoji codepoint, drop
10//!   modifiers. `👨‍👩‍👧` becomes `👨👩👧`.
11//! - [`strip_all_emoji`] — drop everything in the emoji blocks too.
12//!
13//! ## Example
14//!
15//! ```
16//! use emoji_sanitize::{strip_modifiers, strip_all_emoji};
17//! let s = "Hi \u{1F468}\u{200D}\u{1F469}\u{200D}\u{1F467}!";
18//! assert_eq!(strip_modifiers(s), "Hi \u{1F468}\u{1F469}\u{1F467}!");
19//! ```
20
21#![deny(missing_docs)]
22
23/// Strip variation selectors, ZWJ, and skin-tone modifiers — keeping
24/// the base emoji codepoints.
25pub fn strip_modifiers(s: &str) -> String {
26    s.chars().filter(|c| !is_modifier(*c)).collect()
27}
28
29/// Strip everything we recognize as emoji or emoji-modifier.
30pub fn strip_all_emoji(s: &str) -> String {
31    s.chars()
32        .filter(|c| !is_modifier(*c) && !is_emoji(*c))
33        .collect()
34}
35
36/// True for emoji codepoints in the common ranges (BMP misc symbols,
37/// SMP misc, SMP supplemental, emoticons, transport/map symbols).
38pub fn is_emoji(c: char) -> bool {
39    matches!(c as u32,
40        0x1F300..=0x1F5FF // misc symbols / pictographs
41        | 0x1F600..=0x1F64F // emoticons
42        | 0x1F680..=0x1F6FF // transport / map
43        | 0x1F700..=0x1F77F // alchemy
44        | 0x1F780..=0x1F7FF // geometric
45        | 0x1F800..=0x1F8FF // supplemental arrows-c
46        | 0x1F900..=0x1F9FF // supplemental symbols/pictographs
47        | 0x1FA00..=0x1FA6F // chess + extended
48        | 0x1FA70..=0x1FAFF // symbols and pictographs extended-A
49        | 0x2600..=0x26FF   // misc symbols
50        | 0x2700..=0x27BF   // dingbats
51    )
52}
53
54fn is_modifier(c: char) -> bool {
55    matches!(c as u32,
56        0x200D            // ZWJ
57        | 0xFE00..=0xFE0F // variation selectors 1-16 (incl. VS16)
58        | 0x1F3FB..=0x1F3FF // skin tones
59    )
60}