all repos — bibel @ 963a6d5d678e7b9a92c39e6a1d018000b974d92e

Unnamed repository; edit this file 'description' to name the repository.

internal/loader.go (view raw)

  1package bible
  2
  3import (
  4	"encoding/json"
  5	"os"
  6)
  7
  8// Bible represents the complete Bible data
  9type Bible struct {
 10	Metadata struct {
 11		Name    string `json:"name"`
 12		Lang    string `json:"lang_short"`
 13	} `json:"metadata"`
 14	Verses []Verse `json:"verses"`
 15	
 16	// Index for quick lookups
 17	byBookChapterVerse map[int]map[int]map[int]*Verse
 18}
 19
 20// LoadBible loads Bible data from a JSON file
 21func LoadBible(filePath string) (*Bible, error) {
 22	data, err := os.ReadFile(filePath)
 23	if err != nil {
 24		return nil, err
 25	}
 26	
 27	var bible Bible
 28	if err := json.Unmarshal(data, &bible); err != nil {
 29		return nil, err
 30	}
 31	
 32	bible.buildIndex()
 33	return &bible, nil
 34}
 35
 36// buildIndex creates a lookup index for verses
 37func (b *Bible) buildIndex() {
 38	b.byBookChapterVerse = make(map[int]map[int]map[int]*Verse)
 39	
 40	for i := range b.Verses {
 41		verse := &b.Verses[i]
 42		
 43		if b.byBookChapterVerse[verse.Book] == nil {
 44			b.byBookChapterVerse[verse.Book] = make(map[int]map[int]*Verse)
 45		}
 46		
 47		if b.byBookChapterVerse[verse.Book][verse.Chapter] == nil {
 48			b.byBookChapterVerse[verse.Book][verse.Chapter] = make(map[int]*Verse)
 49		}
 50		
 51		b.byBookChapterVerse[verse.Book][verse.Chapter][verse.VerseNum] = verse
 52	}
 53}
 54
 55// GetVerse retrieves a specific verse
 56func (b *Bible) GetVerse(book, chapter, verse int) (*Verse, bool) {
 57	if chapterMap, ok := b.byBookChapterVerse[book]; ok {
 58		if verseMap, ok := chapterMap[chapter]; ok {
 59			if verse, ok := verseMap[verse]; ok {
 60				return verse, true
 61			}
 62		}
 63	}
 64	return nil, false
 65}
 66
 67// GetChapterText retrieves the full text of a chapter
 68func (b *Bible) GetChapterText(book, chapter int) string {
 69	if chapterMap, ok := b.byBookChapterVerse[book]; ok {
 70		if verseMap, ok := chapterMap[chapter]; ok {
 71			var text string
 72			// We need to get verses in order
 73			// Since we don't know the max verse number, we'll iterate
 74			// This could be optimized but works for now
 75			for i := 1; ; i++ {
 76				if verse, ok := verseMap[i]; ok {
 77					text += verse.Text + " "
 78				} else {
 79					break
 80				}
 81			}
 82			return text
 83		}
 84	}
 85	return ""
 86}
 87
 88// CountVersesInChapter returns the number of verses in a chapter
 89func (b *Bible) CountVersesInChapter(book, chapter int) int {
 90	if chapterMap, ok := b.byBookChapterVerse[book]; ok {
 91		if verseMap, ok := chapterMap[chapter]; ok {
 92			return len(verseMap)
 93		}
 94	}
 95	return 0
 96}
 97
 98// GetVerseRange retrieves verses in a range
 99func (b *Bible) GetVerseRange(book, chapter, firstVerse, lastVerse int) []*Verse {
100	var verses []*Verse
101	
102	if chapterMap, ok := b.byBookChapterVerse[book]; ok {
103		if verseMap, ok := chapterMap[chapter]; ok {
104			for i := firstVerse; i <= lastVerse; i++ {
105				if verse, ok := verseMap[i]; ok {
106					verses = append(verses, verse)
107				}
108			}
109		}
110	}
111	
112	return verses
113}