cache Book.sentences as stored let property, add sentencesAreCached test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-14 05:24:42 +01:00
parent 60fef9c75b
commit c5999f6855
2 changed files with 11 additions and 6 deletions

View File

@@ -6,16 +6,14 @@ public struct Book: Sendable {
public let title: String
public let author: String?
public let chapters: [Chapter]
public let sentences: [Sentence]
public init(id: UUID = UUID(), title: String, author: String?, chapters: [Chapter]) {
self.id = id
self.title = title
self.author = author
self.chapters = chapters
}
/// All sentences across all chapters, with global character offsets.
public var sentences: [Sentence] {
var result: [Sentence] = []
var offset: CharacterOffset = 0
for chapter in chapters {
@@ -23,13 +21,12 @@ public struct Book: Sendable {
result.append(contentsOf: chapterSentences)
offset += chapter.text.count
}
return result
self.sentences = result
}
/// Returns the sentence index containing the given global character offset.
public func sentenceIndex(containing offset: CharacterOffset) -> Int? {
let allSentences = sentences
return allSentences.firstIndex { $0.range.contains(offset) }
sentences.firstIndex { $0.range.contains(offset) }
}
/// Maps a global character offset to (chapter index, local offset within chapter).

View File

@@ -54,4 +54,12 @@ struct BookCharacterAddressingTests {
@Test func outOfRangeReturnsNil() {
#expect(book.chapterAndLocalOffset(for: 9999) == nil)
}
@Test func sentencesAreCached() {
let s1 = book.sentences
let s2 = book.sentences
#expect(s1.count == s2.count)
#expect(s1[0].text == s2[0].text)
#expect(s1[0].range == s2[0].range)
}
}