Skip to main content

agentic_codebase/types/
span.rs

1//! Source location types for tracking where code units appear in source files.
2
3use serde::{Deserialize, Serialize};
4
5/// A location range in source code.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub struct Span {
8    /// Starting line (1-indexed).
9    pub start_line: u32,
10    /// Starting column (0-indexed, byte offset).
11    pub start_col: u32,
12    /// Ending line (1-indexed).
13    pub end_line: u32,
14    /// Ending column (0-indexed, byte offset).
15    pub end_col: u32,
16}
17
18impl Span {
19    /// Creates a new span from start and end positions.
20    pub fn new(start_line: u32, start_col: u32, end_line: u32, end_col: u32) -> Self {
21        Self {
22            start_line,
23            start_col,
24            end_line,
25            end_col,
26        }
27    }
28
29    /// Creates a single-point span (zero-width).
30    pub fn point(line: u32, col: u32) -> Self {
31        Self::new(line, col, line, col)
32    }
33
34    /// Returns the number of lines this span covers.
35    pub fn line_count(&self) -> u32 {
36        self.end_line.saturating_sub(self.start_line) + 1
37    }
38
39    /// Returns true if the given position is within this span.
40    pub fn contains(&self, line: u32, col: u32) -> bool {
41        if line < self.start_line || line > self.end_line {
42            return false;
43        }
44        if line == self.start_line && col < self.start_col {
45            return false;
46        }
47        if line == self.end_line && col > self.end_col {
48            return false;
49        }
50        true
51    }
52}
53
54impl std::fmt::Display for Span {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        write!(
57            f,
58            "{}:{}-{}:{}",
59            self.start_line, self.start_col, self.end_line, self.end_col
60        )
61    }
62}