Skip to content

feat(models): add LineNumber newtype to replace raw usize for start_line/end_line#596

Merged
abraemer merged 1 commit intomainfrom
feat/line-number-newtypes
Apr 9, 2026
Merged

feat(models): add LineNumber newtype to replace raw usize for start_line/end_line#596
abraemer merged 1 commit intomainfrom
feat/line-number-newtypes

Conversation

@abraemer
Copy link
Copy Markdown
Collaborator

@abraemer abraemer commented Apr 9, 2026

Summary

  • Introduce LineNumber (backed by NonZeroUsize) and LineSpan newtypes to replace raw usize fields for start_line/end_line across the entire codebase
  • Eliminate the possibility of invalid zero-valued line numbers at the type level, removing runtime guards that checked for start_line > 0
  • Make the 1-indexed semantics of line numbers explicit in the type system

Key changes

  • New src/models/line_number.rs with LineNumber(NonZeroUsize) and LineSpan { start, end } types
  • All output structs (Match, Copyright, Holder, Author, OutputEmail, OutputURL) now use LineNumber for start_line/end_line
  • All internal detection types (CopyrightDetection, HolderDetection, AuthorDetection, Token, EmailDetection, UrlDetection, LicenseMatch, FileRegion, DeclaredLicenseMatchMetadata) migrated
  • SerializableLicenseMatch preserves JSON backward compatibility via serde(transparent) on LineNumber
  • Removed now-unnecessary start_line > 0 / end_line > 0 runtime guards
  • line_for_pos() returns Option<LineNumber> instead of Option<usize>
  • matched_text_from_text() takes (LineNumber, LineNumber) params
  • ranges_overlap() takes LineNumber params (Ord-based comparison)
  • LineSpan defined but not yet adopted (for future use)
  • LicenseMatch::default() uses LineNumber::ONE instead of 0

Performance

Neutral — NonZeroUsize has the same layout as usize, and Option<LineNumber> benefits from niche optimization (same size as Option<usize>).

Testing

  • cargo build — 0 errors
  • cargo fmt — clean
  • cargo clippy --all-targets --all-features — 0 errors
  • Targeted tests pass (license detection models, finder, debian parser, line-number specific tests)
  • 1 pre-existing test failure unrelated to this change

How I tested

Ran targeted test suites for copyright detection, license detection models, finder, and debian parser modules. All pass except one pre-existing failure in test_normalize_company_suffix_period_holder_variants.

@abraemer abraemer force-pushed the feat/digest-newtypes branch from ec871c8 to d635146 Compare April 9, 2026 16:18
@abraemer abraemer marked this pull request as draft April 9, 2026 16:34
@abraemer abraemer force-pushed the feat/digest-newtypes branch from d635146 to b30a5e1 Compare April 9, 2026 17:45
@abraemer abraemer force-pushed the feat/line-number-newtypes branch 4 times, most recently from 8f6f942 to 571938e Compare April 9, 2026 19:26
…ine/end_line

Introduce LineNumber (backed by NonZeroUsize) and LineSpan newtypes to
replace raw usize fields for start_line/end_line across all output,
detection, and internal types. This eliminates the possibility of
invalid zero-valued line numbers at the type level, removes runtime
guards that checked for start_line > 0, and makes the 1-indexed
semantics explicit in the type system.

Key changes:
- New src/models/line_number.rs with LineNumber(NonZeroUsize) and
  LineSpan { start, end } types
- All output structs (Match, Copyright, Holder, Author, OutputEmail,
  OutputURL) now use LineNumber for start_line/end_line
- All internal detection types (CopyrightDetection, HolderDetection,
  AuthorDetection, Token, EmailDetection, UrlDetection, LicenseMatch,
  FileRegion, DeclaredLicenseMatchMetadata) migrated
- SerializableLicenseMatch preserves JSON backward compatibility via
  serde(transparent) on LineNumber
- Removed now-unnecessary start_line > 0 / end_line > 0 guards
- line_for_pos() returns Option<LineNumber> instead of Option<usize>
- matched_text_from_text() takes (LineNumber, LineNumber) params
- ranges_overlap() takes LineNumber params (Ord-based comparison)
- LineSpan defined but not yet adopted (for future use)
@abraemer abraemer force-pushed the feat/line-number-newtypes branch from 571938e to ad4e59d Compare April 9, 2026 19:50
Base automatically changed from feat/digest-newtypes to main April 9, 2026 20:44
@abraemer abraemer marked this pull request as ready for review April 9, 2026 20:44
@abraemer abraemer merged commit d3f4161 into main Apr 9, 2026
14 checks passed
@abraemer abraemer deleted the feat/line-number-newtypes branch April 9, 2026 20:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant