1use std::fmt;
2
3use crate::verse::Verse;
4
5#[derive(Debug, Clone)]
9pub struct Chapter {
10 verses: Vec<Verse>,
11 chapter_number: usize,
12}
13
14impl Chapter {
15 pub fn new(verses: Vec<Verse>, chapter_number: usize) -> Self {
22 Chapter {
23 verses,
24 chapter_number,
25 }
26 }
27
28 pub fn number(&self) -> usize {
30 self.chapter_number
31 }
32
33 pub fn get_verses(&self) -> &[Verse] {
39 &self.verses
40 }
41
42 pub fn get_verse(&self, verse_number: usize) -> Option<&Verse> {
52 if verse_number == 0 {
53 return None;
54 }
55 self.verses.get(verse_number - 1)
56 }
57}
58
59impl fmt::Display for Chapter {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 let verses_str = self
62 .verses
63 .iter()
64 .map(|v| format!("{}", v))
65 .collect::<Vec<String>>()
66 .join("\n");
67 write!(f, "Chapter {}:\n{}", self.chapter_number, verses_str)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::bible_books_enum::BibleBook;
75
76 #[test]
77 fn test_new_and_accessors() {
78 let verses = vec![Verse::new(BibleBook::Genesis, 1, 1, "Test".into())];
79 let chapter = Chapter::new(verses, 1);
80 assert_eq!(chapter.number(), 1);
81 assert_eq!(chapter.get_verses().len(), 1);
82 assert_eq!(chapter.get_verse(1).unwrap().number(), 1);
83 assert!(chapter.get_verse(0).is_none());
84 }
85
86 #[test]
87 fn test_clone_independence() {
88 let verses = vec![Verse::new(BibleBook::Genesis, 1, 1, "Clone".into())];
89 let original = Chapter::new(verses, 1);
90 let cloned = original.clone();
91
92 assert_eq!(original.number(), cloned.number());
93 assert_eq!(original.get_verses().len(), cloned.get_verses().len());
94 assert_eq!(
95 original.get_verses()[0].text(),
96 cloned.get_verses()[0].text()
97 );
98
99 assert_ne!(original.get_verses().as_ptr(), cloned.get_verses().as_ptr());
101 assert_ne!(
102 original.get_verses()[0].text().as_ptr(),
103 cloned.get_verses()[0].text().as_ptr()
104 );
105 }
106}