Skip to main content

hyperstack_idl/
error.rs

1//! Error types for IDL search and lookup operations
2
3use crate::search::Suggestion;
4
5/// Structured error type for IDL lookup operations.
6///
7/// Named `IdlSearchError` to avoid conflict with `types::IdlError`
8/// which represents error definitions within an IDL spec.
9#[derive(Debug, Clone)]
10pub enum IdlSearchError {
11    NotFound {
12        input: String,
13        section: String,
14        suggestions: Vec<Suggestion>,
15        available: Vec<String>,
16    },
17    ParseError {
18        path: String,
19        source: String,
20    },
21    InvalidPath {
22        path: String,
23    },
24}
25
26impl std::fmt::Display for IdlSearchError {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match self {
29            IdlSearchError::NotFound {
30                input,
31                section,
32                suggestions,
33                available,
34            } => {
35                write!(f, "Not found: '{}' in {}", input, section)?;
36                if !suggestions.is_empty() {
37                    write!(f, ". Did you mean: {}?", suggestions[0].candidate)?;
38                } else if !available.is_empty() {
39                    let preview = available
40                        .iter()
41                        .take(5)
42                        .cloned()
43                        .collect::<Vec<_>>()
44                        .join(", ");
45                    write!(f, ". {}: {}", available_label(section), preview)?;
46                }
47                Ok(())
48            }
49            IdlSearchError::ParseError { path, source } => {
50                write!(f, "Failed to parse '{}': {}", path, source)
51            }
52            IdlSearchError::InvalidPath { path } => {
53                write!(
54                    f,
55                    "Invalid path '{}'. Expected a Rust path like foo::bar::Baz",
56                    path
57                )
58            }
59        }
60    }
61}
62
63impl std::error::Error for IdlSearchError {}
64
65fn available_label(section: &str) -> String {
66    if section.starts_with("instruction fields") {
67        "Available instruction fields".to_string()
68    } else if section.starts_with("account fields") {
69        "Available account fields".to_string()
70    } else {
71        format!("Available {}", section)
72    }
73}