codineer_plugins/
error.rs1use std::fmt::{Display, Formatter};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum PluginManifestValidationError {
6 EmptyField {
7 field: &'static str,
8 },
9 EmptyEntryField {
10 kind: &'static str,
11 field: &'static str,
12 name: Option<String>,
13 },
14 InvalidPermission {
15 permission: String,
16 },
17 DuplicatePermission {
18 permission: String,
19 },
20 DuplicateEntry {
21 kind: &'static str,
22 name: String,
23 },
24 MissingPath {
25 kind: &'static str,
26 path: PathBuf,
27 },
28 InvalidToolInputSchema {
29 tool_name: String,
30 },
31 InvalidToolRequiredPermission {
32 tool_name: String,
33 permission: String,
34 },
35}
36
37impl Display for PluginManifestValidationError {
38 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
39 match self {
40 Self::EmptyField { field } => {
41 write!(f, "plugin manifest {field} cannot be empty")
42 }
43 Self::EmptyEntryField { kind, field, name } => match name {
44 Some(name) if !name.is_empty() => {
45 write!(f, "plugin {kind} `{name}` {field} cannot be empty")
46 }
47 _ => write!(f, "plugin {kind} {field} cannot be empty"),
48 },
49 Self::InvalidPermission { permission } => {
50 write!(
51 f,
52 "plugin manifest permission `{permission}` must be one of read, write, or execute"
53 )
54 }
55 Self::DuplicatePermission { permission } => {
56 write!(f, "plugin manifest permission `{permission}` is duplicated")
57 }
58 Self::DuplicateEntry { kind, name } => {
59 write!(f, "plugin {kind} `{name}` is duplicated")
60 }
61 Self::MissingPath { kind, path } => {
62 write!(f, "{kind} path `{}` does not exist", path.display())
63 }
64 Self::InvalidToolInputSchema { tool_name } => {
65 write!(
66 f,
67 "plugin tool `{tool_name}` inputSchema must be a JSON object"
68 )
69 }
70 Self::InvalidToolRequiredPermission {
71 tool_name,
72 permission,
73 } => write!(
74 f,
75 "plugin tool `{tool_name}` requiredPermission `{permission}` must be read-only, workspace-write, or danger-full-access"
76 ),
77 }
78 }
79}
80
81#[derive(Debug)]
82pub enum PluginError {
83 Io(std::io::Error),
84 Json(serde_json::Error),
85 ManifestValidation(Vec<PluginManifestValidationError>),
86 InvalidManifest(String),
87 NotFound(String),
88 CommandFailed(String),
89}
90
91impl Display for PluginError {
92 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
93 match self {
94 Self::Io(error) => write!(f, "{error}"),
95 Self::Json(error) => write!(f, "{error}"),
96 Self::ManifestValidation(errors) => {
97 for (index, error) in errors.iter().enumerate() {
98 if index > 0 {
99 write!(f, "; ")?;
100 }
101 write!(f, "{error}")?;
102 }
103 Ok(())
104 }
105 Self::InvalidManifest(message)
106 | Self::NotFound(message)
107 | Self::CommandFailed(message) => write!(f, "{message}"),
108 }
109 }
110}
111
112impl std::error::Error for PluginError {}
113
114impl From<std::io::Error> for PluginError {
115 fn from(value: std::io::Error) -> Self {
116 Self::Io(value)
117 }
118}
119
120impl From<serde_json::Error> for PluginError {
121 fn from(value: serde_json::Error) -> Self {
122 Self::Json(value)
123 }
124}