nur-dev's picture
Add files using upload-large-folder tool
e69b72a verified
Raw
History Blame Contribute Delete
2.31 kB
"""Shared typed data structures used across STRATA modules."""
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class CharSpan:
"""Half-open character span in Python string coordinates."""
start: int
end: int
def __post_init__(self) -> None:
if self.start < 0:
raise ValueError(f"char span start must be non-negative, got {self.start}")
if self.end < self.start:
raise ValueError(
f"char span end must be >= start, got start={self.start}, end={self.end}"
)
@property
def length(self) -> int:
return self.end - self.start
def overlaps(self, other: "CharSpan") -> bool:
return self.start < other.end and other.start < self.end
def contains(self, other: "CharSpan") -> bool:
return self.start <= other.start and other.end <= self.end
@dataclass(frozen=True, slots=True)
class ByteSpan:
"""Half-open byte span in UTF-8 encoded coordinates."""
start: int
end: int
def __post_init__(self) -> None:
if self.start < 0:
raise ValueError(f"byte span start must be non-negative, got {self.start}")
if self.end < self.start:
raise ValueError(
f"byte span end must be >= start, got start={self.start}, end={self.end}"
)
@property
def length(self) -> int:
return self.end - self.start
def overlaps(self, other: "ByteSpan") -> bool:
return self.start < other.end and other.start < self.end
def contains(self, other: "ByteSpan") -> bool:
return self.start <= other.start and other.end <= self.end
@dataclass(frozen=True, slots=True)
class AnchoredSpan:
"""Span carrying both character and byte coordinates."""
char: CharSpan
byte: ByteSpan
@classmethod
def from_offsets(
cls,
*,
char_start: int,
char_end: int,
byte_start: int,
byte_end: int,
) -> "AnchoredSpan":
return cls(
char=CharSpan(char_start, char_end),
byte=ByteSpan(byte_start, byte_end),
)
def overlaps(self, other: "AnchoredSpan") -> bool:
return self.byte.overlaps(other.byte) and self.char.overlaps(other.char)