use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all(deserialize = "lowercase"))]
pub struct Title {
romaji: Option<String>,
english: Option<String>,
native: String,
user_preferred: Option<String>,
}
impl Title {
pub fn romaji(&self) -> &str {
self.romaji.as_deref().unwrap_or(&self.native)
}
pub fn english(&self) -> &str {
self.english.as_deref().unwrap_or(&self.native)
}
pub fn native(&self) -> &str {
&self.native
}
pub fn user_preferred(&self) -> &str {
self.user_preferred.as_deref().unwrap_or(&self.native)
}
pub fn is_empty(&self) -> bool {
self.romaji.is_none()
&& self.english.is_none()
&& self.native.is_empty()
&& self.user_preferred.is_none()
}
}
impl From<Title> for String {
fn from(title: Title) -> Self {
title.native().to_string()
}
}
impl std::fmt::Display for Title {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.native())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_romaji_with_romaji() {
let title = Title {
romaji: Some("Romaji Title".to_string()),
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.romaji(), "Romaji Title");
}
#[test]
fn test_romaji_without_romaji() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.romaji(), "Native Title");
}
#[test]
fn test_english_with_english() {
let title = Title {
romaji: None,
english: Some("English Title".to_string()),
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.english(), "English Title");
}
#[test]
fn test_english_without_english() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.english(), "Native Title");
}
#[test]
fn test_native() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.native(), "Native Title");
}
#[test]
fn test_user_preferred_with_user_preferred() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: Some("User Preferred Title".to_string()),
};
assert_eq!(title.user_preferred(), "User Preferred Title");
}
#[test]
fn test_user_preferred_without_user_preferred() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
assert_eq!(title.user_preferred(), "Native Title");
}
#[test]
fn test_is_empty_all_none_and_empty() {
let title = Title {
romaji: None,
english: None,
native: String::new(),
user_preferred: None,
};
assert!(title.is_empty());
}
#[test]
fn test_is_empty_romaji_some() {
let title = Title {
romaji: Some(String::from("Romaji")),
english: None,
native: String::new(),
user_preferred: None,
};
assert!(!title.is_empty());
}
#[test]
fn test_is_empty_english_some() {
let title = Title {
romaji: None,
english: Some(String::from("English")),
native: String::new(),
user_preferred: None,
};
assert!(!title.is_empty());
}
#[test]
fn test_is_empty_native_not_empty() {
let title = Title {
romaji: None,
english: None,
native: String::from("Native"),
user_preferred: None,
};
assert!(!title.is_empty());
}
#[test]
fn test_is_empty_user_preferred_some() {
let title = Title {
romaji: None,
english: None,
native: String::new(),
user_preferred: Some(String::from("User Preferred")),
};
assert!(!title.is_empty());
}
#[test]
fn test_from_title_to_string() {
let title = Title {
romaji: None,
english: None,
native: "Native Title".to_string(),
user_preferred: None,
};
let title_string: String = title.into();
assert_eq!(title_string, "Native Title");
}
}