ass_editor/core/position/selection.rs
1//! Directional text selection type.
2//!
3//! Defines [`Selection`], which pairs an anchor and cursor [`Position`]
4//! to track selection direction and expose the covered [`Range`].
5
6use super::{Position, Range};
7
8/// Selection represents a range with a direction
9///
10/// The anchor is where the selection started, and the cursor
11/// is where it currently ends. This allows tracking selection direction.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct Selection {
14 /// Where the selection started
15 pub anchor: Position,
16 /// Where the selection cursor is
17 pub cursor: Position,
18}
19
20impl Selection {
21 /// Create a new selection
22 #[must_use]
23 pub const fn new(anchor: Position, cursor: Position) -> Self {
24 Self { anchor, cursor }
25 }
26
27 /// Create an empty selection at position
28 #[must_use]
29 pub const fn empty(pos: Position) -> Self {
30 Self {
31 anchor: pos,
32 cursor: pos,
33 }
34 }
35
36 /// Check if selection is empty (no selected text)
37 #[must_use]
38 pub const fn is_empty(&self) -> bool {
39 self.anchor.offset == self.cursor.offset
40 }
41
42 /// Get the range covered by this selection (normalized)
43 #[must_use]
44 pub fn range(&self) -> Range {
45 Range::new(self.anchor, self.cursor)
46 }
47
48 /// Check if selection is reversed (cursor before anchor)
49 #[must_use]
50 pub const fn is_reversed(&self) -> bool {
51 self.cursor.offset < self.anchor.offset
52 }
53
54 /// Extend selection to include a position
55 #[must_use]
56 pub const fn extend_to(&self, pos: Position) -> Self {
57 Self {
58 anchor: self.anchor,
59 cursor: pos,
60 }
61 }
62}