2021-02-16 21:29:45 +00:00
|
|
|
use common::character::MAX_NAME_LENGTH;
|
2020-07-16 14:05:35 +00:00
|
|
|
use std::fmt::{self, Display};
|
|
|
|
|
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct AliasValidator {
|
|
|
|
banned_substrings: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AliasValidator {
|
|
|
|
pub fn new(banned_substrings: Vec<String>) -> Self {
|
|
|
|
let banned_substrings = banned_substrings
|
|
|
|
.iter()
|
|
|
|
.map(|string| string.to_lowercase())
|
|
|
|
.collect();
|
|
|
|
|
|
|
|
AliasValidator { banned_substrings }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn validate(&self, alias: &str) -> Result<(), ValidatorError> {
|
2021-02-16 21:29:45 +00:00
|
|
|
if alias.len() > MAX_NAME_LENGTH {
|
|
|
|
return Err(ValidatorError::TooLong(alias.to_owned(), alias.len()));
|
|
|
|
}
|
|
|
|
|
2020-07-16 14:05:35 +00:00
|
|
|
let lowercase_alias = alias.to_lowercase();
|
|
|
|
|
|
|
|
for banned_word in self.banned_substrings.iter() {
|
|
|
|
if lowercase_alias.contains(banned_word) {
|
|
|
|
return Err(ValidatorError::Forbidden(
|
|
|
|
alias.to_owned(),
|
|
|
|
banned_word.to_owned(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq)]
|
|
|
|
pub enum ValidatorError {
|
|
|
|
Forbidden(String, String),
|
2021-02-16 21:29:45 +00:00
|
|
|
TooLong(String, usize),
|
2020-07-16 14:05:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for ValidatorError {
|
|
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::Forbidden(name, _) => write!(
|
|
|
|
formatter,
|
|
|
|
"Character name \"{}\" contains a banned word",
|
|
|
|
name
|
|
|
|
),
|
2021-02-16 21:29:45 +00:00
|
|
|
Self::TooLong(name, _) => write!(formatter, "Character name \"{}\" too long", name),
|
2020-07-16 14:05:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn multiple_matches() {
|
|
|
|
let banned_substrings = vec!["bad".to_owned(), "worse".to_owned()];
|
|
|
|
let validator = AliasValidator::new(banned_substrings);
|
|
|
|
|
2021-02-16 21:29:45 +00:00
|
|
|
let bad_alias = "BadplayerMcWorseFace";
|
2020-07-16 14:05:35 +00:00
|
|
|
let result = validator.validate(bad_alias);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
result,
|
|
|
|
Err(ValidatorError::Forbidden(
|
|
|
|
bad_alias.to_owned(),
|
|
|
|
"bad".to_owned()
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn single_lowercase_match() {
|
|
|
|
let banned_substrings = vec!["blue".to_owned()];
|
|
|
|
let validator = AliasValidator::new(banned_substrings);
|
|
|
|
|
|
|
|
let bad_alias = "blueName";
|
|
|
|
let result = validator.validate(bad_alias);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
result,
|
|
|
|
Err(ValidatorError::Forbidden(
|
|
|
|
bad_alias.to_owned(),
|
|
|
|
"blue".to_owned()
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn single_case_insensitive_match() {
|
|
|
|
let banned_substrings = vec!["GrEEn".to_owned()];
|
|
|
|
let validator = AliasValidator::new(banned_substrings);
|
|
|
|
|
|
|
|
let bad_alias = "gReenName";
|
|
|
|
let result = validator.validate(bad_alias);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
result,
|
|
|
|
Err(ValidatorError::Forbidden(
|
|
|
|
bad_alias.to_owned(),
|
|
|
|
"green".to_owned()
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn mp_matches() {
|
|
|
|
let banned_substrings = vec!["orange".to_owned()];
|
|
|
|
let validator = AliasValidator::new(banned_substrings);
|
|
|
|
|
|
|
|
let good_alias = "ReasonableName";
|
|
|
|
let result = validator.validate(good_alias);
|
|
|
|
|
|
|
|
assert_eq!(result, Ok(()));
|
|
|
|
}
|
2021-02-16 21:29:45 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn too_long() {
|
|
|
|
let banned_substrings = vec!["orange".to_owned()];
|
|
|
|
let validator = AliasValidator::new(banned_substrings);
|
|
|
|
|
|
|
|
let bad_alias = "Thisnameistoolong Muchtoolong MuchTooLongByFar";
|
|
|
|
let result = validator.validate(bad_alias);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
result,
|
|
|
|
Err(ValidatorError::TooLong(
|
|
|
|
bad_alias.to_owned(),
|
|
|
|
bad_alias.chars().count()
|
|
|
|
))
|
|
|
|
);
|
|
|
|
}
|
2020-07-16 14:05:35 +00:00
|
|
|
}
|