codex_execpolicy/
error.rs1use starlark::Error as StarlarkError;
2use thiserror::Error;
3
4pub type Result<T> = std::result::Result<T, Error>;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct TextPosition {
8 pub line: usize,
9 pub column: usize,
10}
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct TextRange {
14 pub start: TextPosition,
15 pub end: TextPosition,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct ErrorLocation {
20 pub path: String,
21 pub range: TextRange,
22}
23
24#[derive(Debug, Error)]
25pub enum Error {
26 #[error("invalid decision: {0}")]
27 InvalidDecision(String),
28 #[error("invalid pattern element: {0}")]
29 InvalidPattern(String),
30 #[error("invalid example: {0}")]
31 InvalidExample(String),
32 #[error("invalid rule: {0}")]
33 InvalidRule(String),
34 #[error(
35 "expected every example to match at least one rule. rules: {rules:?}; unmatched examples: \
36 {examples:?}"
37 )]
38 ExampleDidNotMatch {
39 rules: Vec<String>,
40 examples: Vec<String>,
41 location: Option<ErrorLocation>,
42 },
43 #[error("expected example to not match rule `{rule}`: {example}")]
44 ExampleDidMatch {
45 rule: String,
46 example: String,
47 location: Option<ErrorLocation>,
48 },
49 #[error("starlark error: {0}")]
50 Starlark(StarlarkError),
51}
52
53impl Error {
54 pub fn with_location(self, location: ErrorLocation) -> Self {
55 match self {
56 Error::ExampleDidNotMatch {
57 rules,
58 examples,
59 location: None,
60 } => Error::ExampleDidNotMatch {
61 rules,
62 examples,
63 location: Some(location),
64 },
65 Error::ExampleDidMatch {
66 rule,
67 example,
68 location: None,
69 } => Error::ExampleDidMatch {
70 rule,
71 example,
72 location: Some(location),
73 },
74 other => other,
75 }
76 }
77
78 pub fn location(&self) -> Option<ErrorLocation> {
79 match self {
80 Error::ExampleDidNotMatch { location, .. }
81 | Error::ExampleDidMatch { location, .. } => location.clone(),
82 Error::Starlark(err) => err.span().map(|span| {
83 let resolved = span.resolve_span();
84 ErrorLocation {
85 path: span.filename().to_string(),
86 range: TextRange {
87 start: TextPosition {
88 line: resolved.begin.line + 1,
89 column: resolved.begin.column + 1,
90 },
91 end: TextPosition {
92 line: resolved.end.line + 1,
93 column: resolved.end.column + 1,
94 },
95 },
96 }
97 }),
98 _ => None,
99 }
100 }
101}