The first encoding is the one you find in many languages, and for example in JSON. It differs from Rust literals in which you have \u{2122} instead of \u2122.
This gives us a solution: parse it as JSON.
let s = "HITMAN\\u2122 Free Trial";
let s: String = serde_json::from_str(&format!("\"{}\"", s)).unwrap();
assert_eq!(
s,
"HITMAN™ Free Trial",
);
But while this is useful as validation, you probably don't want to include a deserializer just for this, so you probably want to do the parsing yourself, for example with a regular expression:
use lazy_regex::*;
let s = "HITMAN\\u2122 Free Trial";
let s = regex_replace_all!(r#"\\u(\d{4})"#, s, |_, num: &str| {
let num: u32 = u32::from_str_radix(num, 16).unwrap();
let c: char = std::char::from_u32(num).unwrap();
c.to_string()
});
assert_eq!(
s,
"HITMAN™ Free Trial",
);
"HITMAN™ Free Trial"in source code using the\uescape or convert"HITMAN\\u2122 Free Trial"at runtime?