🌡️
Rustでオブジェクト設計&バリデーション(ガード節)"^[A-Za-z0-9_-]+$"
main.rs
[dependencies]
regex = "1.4"
struct Username {
username_min_length: usize,
username_max_length: usize,
username_valid_characters: regex::Regex, //ここまでクラス変数
username: String,
}
impl Username {
const USERNAME_MINIMUM_LENGTH: usize = 4;
const USERNAME_MAXIMUM_LENGTH: usize = 40;
const USERNAME_VALID_CHARACTERS: &str = "^[A-Za-z0-9_-]+$";
fn new(username: &str) -> Result<Self, String> {
let re = regex::Regex::new(Self::USERNAME_VALID_CHARACTERS).unwrap();
let stripped_username = username.trim().to_string();
// ガード節
let result = Self::validate_username(&re, &stripped_username);
match result {
Ok(_) => Ok(Username {
username_min_length: Self::USERNAME_MINIMUM_LENGTH,
username_max_length: Self::USERNAME_MAXIMUM_LENGTH,
username_valid_characters: re,
username: stripped_username,
}),
Err(err) => Err(err),
}
}
fn validate_username(re: ®ex::Regex, username: &str) -> Result<(), String> {
if username.is_empty() {
return Err("Username cannot be blank".to_string());
}
let username_length = username.len();
if username_length < Self::USERNAME_MINIMUM_LENGTH || username_length > Self::USERNAME_MAXIMUM_LENGTH {
return Err(format!(
"Username length should be between {} and {}",
Self::USERNAME_MINIMUM_LENGTH, Self::USERNAME_MAXIMUM_LENGTH
));
}
if !re.is_match(username) {
return Err(format!(
"Username contains invalid characters. Allowed characters are: {}",
Self::USERNAME_VALID_CHARACTERS
));
}
Ok(())
}
fn to_string(&self) -> String {
format!("Username(username={})", self.username)
}
}
struct User {
id: i32,
username: Username, //依存の注入
}
impl User {
fn new(id: i32, username: Username) -> Result<Self, String> {
//ガード節
if id == 0 {
return Err("ID cannot be zero".to_string());
}
Ok(User { id, username })
}
fn get_user_info(&self) -> String {
format!("User(id={}, username={})", self.id, self.username.to_string())
}
}
fn main() {
let username1_result = Username::new("my_username123");
match username1_result {
Ok(username1) => {
let user1_result = User::new(1, username1);
match user1_result {
Ok(user1) => println!("{}", user1.get_user_info()),
Err(err) => eprintln!("Validation error: {}", err),
}
}
Err(err) => eprintln!("Validation error: {}", err),
}
let username2_result = Username::new("<script>alert(0101);</script>");
match username2_result {
Ok(username2) => {
let user2_result = User::new(2, username2);
match user2_result {
Ok(user2) => println!("{}", user2.get_user_info()),
Err(err) => eprintln!("Validation error: {}", err),
}
}
Err(err) => eprintln!("Validation error: {}", err),
}
}
出力
User(id=1, username=Username(username=my_username123))
Validation error: Username contains invalid characters. Allowed characters are: ^[A-Za-z0-9_-]+$
Discussion