pub struct Ruler<'a> { /* private fields */ }Expand description
Converts between scales for one specific text.
A Ruler cannot be built without the text, which is the structural reason
a scale conversion can never be done “in general”: there is no such thing.
"héllo".len() is 6 bytes and 5 chars, and only the string knows.
Implementations§
Source§impl<'a> Ruler<'a>
impl<'a> Ruler<'a>
pub const fn new(text: &'a str) -> Ruler<'a>
Sourcepub fn snap(&self, at: Offset<Bytes>) -> Offset<Bytes>
pub fn snap(&self, at: Offset<Bytes>) -> Offset<Bytes>
Clamp into the text and snap DOWN to a character boundary.
Snapping down, not up, keeps the result inside the character the offset
pointed at — where an editor should underline. Mid-codepoint offsets are
a NORMAL arrival, not corruption: they come from parser error spans over
a buffer the user is halfway through typing a character into. Measured
2026-08-01: analyse("🔥🔥🔥") aborted on exactly this at offset 1.
Sourcepub fn to_chars(&self, at: Offset<Bytes>) -> Offset<Chars>
pub fn to_chars(&self, at: Offset<Bytes>) -> Offset<Chars>
Bytes → chars. Total: out-of-range and mid-codepoint inputs snap first.
Sourcepub fn to_bytes(&self, at: Offset<Chars>) -> Offset<Bytes>
pub fn to_bytes(&self, at: Offset<Chars>) -> Offset<Bytes>
Chars → bytes. Total: past-the-end saturates to the text’s end.
Sourcepub fn to_utf16(&self, at: Offset<Bytes>) -> Offset<Utf16Units>
pub fn to_utf16(&self, at: Offset<Bytes>) -> Offset<Utf16Units>
Bytes → UTF-16 code units, for LSP.
Separate from Self::to_chars because they differ, and the
difference is invisible until a user types an emoji: 🔥 is ONE char
and TWO UTF-16 units. Conflating them shifts every position after it.