verseRangeRefFromStr function

VerseRangeRef verseRangeRefFromStr(
  1. String ref, {
  2. BibleLanguageEnum? language,
})

Parse a string into a VerseRangeRef.

Implementation

VerseRangeRef verseRangeRefFromStr(String ref, {BibleLanguageEnum? language}) {
  _ensureReferenceIsNotEmpty(ref);
  final normalizedLanguage = _bookLookup.normalizeLanguage(language);

  final match = _verseRangeRefPattern.firstMatch(ref);
  if (match == null) {
    throw ParseVerseRefError(
        code: 'pattern_mismatch',
        details: 'reference "$ref" does not match expected format');
  }

  final startChapter = _parseReferenceNumber(
    match.group(2)!,
    component: 'start chapter',
    maximum: maxReferenceChapterNumber,
  );
  final startVerse = _parseVerseToken(
    match.group(3)!,
    component: 'start verse',
  );
  final endVerse = _parseVerseToken(
    match.group(6)!,
    component: 'end verse',
  );

  final endChapterMatch = match.group(5);
  final endChapter = endChapterMatch != null
      ? _parseReferenceNumber(
          endChapterMatch,
          component: 'end chapter',
          maximum: maxReferenceChapterNumber,
        )
      : startChapter;

  final startBook =
      _bookLookup.parseBookName(match.group(1)!, normalizedLanguage);
  final endBookMatch = match.group(4);
  final endBook = endBookMatch != null
      ? _bookLookup.parseBookName(endBookMatch, normalizedLanguage)
      : startBook;

  final start = VerseRef(
    book: startBook,
    chapter: startChapter,
    verse: startVerse.verse,
    subdivision: startVerse.subdivision,
  );
  final end = VerseRef(
    book: endBook,
    chapter: endChapter,
    verse: endVerse.verse,
    subdivision: endVerse.subdivision,
  );
  if (endBook == startBook && start.compareTo(end) >= 0) {
    throw ParseVerseRefError(
        code: 'same_book_range_not_ascending',
        details:
            'end reference must come after start reference for same-book ranges');
  }

  if (start.compareTo(end) >= 0) {
    throw ParseVerseRefError.typed(
      code: ReferenceParseErrorCode.crossBookRangeNotAscending,
      details: 'end reference must come after start reference',
    );
  }

  return VerseRangeRef.checked(start: start, end: end);
}