use std::fmt;
use crate::bible_books_enum::BibleBook;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Verse {
book: BibleBook,
chapter_number: usize,
verse_text: String,
verse_number: usize,
}
impl Verse {
pub fn new(
book: BibleBook,
chapter_number: usize,
verse_number: usize,
verse_text: String,
) -> Self {
Verse {
book,
chapter_number,
verse_text: sanitize_verse_text(verse_text),
verse_number,
}
}
pub fn book(&self) -> BibleBook {
self.book
}
pub fn chapter(&self) -> usize {
self.chapter_number
}
pub fn text(&self) -> &str {
&self.verse_text
}
pub fn number(&self) -> usize {
self.verse_number
}
}
fn sanitize_verse_text(verse_text: String) -> String {
verse_text
.chars()
.filter(|c| *c != '{' && *c != '}')
.collect()
}
impl fmt::Display for Verse {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.verse_number, self.verse_text)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_and_accessors() {
let verse = Verse::new(BibleBook::Genesis, 1, 1, "Test".to_string());
assert_eq!(verse.book(), BibleBook::Genesis);
assert_eq!(verse.chapter(), 1);
assert_eq!(verse.text(), "Test");
assert_eq!(verse.number(), 1);
assert_eq!(format!("{}", verse), "1: Test");
}
#[test]
fn test_sanitize_verse_text() {
let verse = Verse::new(BibleBook::Genesis, 1, 1, "In {the} beginning".to_string());
assert_eq!(verse.text(), "In the beginning");
}
#[test]
fn test_clone_independence() {
let original = Verse::new(BibleBook::Genesis, 1, 42, "Clone me".to_string());
let cloned = original.clone();
assert_eq!(original.book(), cloned.book());
assert_eq!(original.chapter(), cloned.chapter());
assert_eq!(original.text(), cloned.text());
assert_eq!(original.number(), cloned.number());
assert_ne!(original.text().as_ptr(), cloned.text().as_ptr());
}
}