1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub enum Permission {
8 Tool(String),
10 AllTools,
12 Agent(String),
14 AllAgents,
16}
17
18impl Permission {
19 pub fn tool(name: impl Into<String>) -> Self {
21 Permission::Tool(name.into())
22 }
23
24 pub fn agent(name: impl Into<String>) -> Self {
26 Permission::Agent(name.into())
27 }
28
29 pub fn matches(&self, resource_type: &str, resource_name: &str) -> bool {
31 match self {
32 Permission::Tool(name) => resource_type == "tool" && name == resource_name,
33 Permission::AllTools => resource_type == "tool",
34 Permission::Agent(name) => resource_type == "agent" && name == resource_name,
35 Permission::AllAgents => resource_type == "agent",
36 }
37 }
38
39 pub fn covers(&self, other: &Permission) -> bool {
41 match (self, other) {
42 (Permission::AllTools, Permission::Tool(_)) => true,
44 (Permission::AllTools, Permission::AllTools) => true,
45 (Permission::AllAgents, Permission::Agent(_)) => true,
47 (Permission::AllAgents, Permission::AllAgents) => true,
48 (a, b) => a == b,
50 }
51 }
52}
53
54impl std::fmt::Display for Permission {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 match self {
57 Permission::Tool(name) => write!(f, "tool:{}", name),
58 Permission::AllTools => write!(f, "tool:*"),
59 Permission::Agent(name) => write!(f, "agent:{}", name),
60 Permission::AllAgents => write!(f, "agent:*"),
61 }
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 #[test]
70 fn test_permission_matches() {
71 let tool_perm = Permission::Tool("search".into());
72 assert!(tool_perm.matches("tool", "search"));
73 assert!(!tool_perm.matches("tool", "other"));
74 assert!(!tool_perm.matches("agent", "search"));
75
76 let all_tools = Permission::AllTools;
77 assert!(all_tools.matches("tool", "anything"));
78 assert!(!all_tools.matches("agent", "anything"));
79 }
80
81 #[test]
82 fn test_permission_covers() {
83 let all_tools = Permission::AllTools;
84 let specific_tool = Permission::Tool("search".into());
85
86 assert!(all_tools.covers(&specific_tool));
87 assert!(all_tools.covers(&Permission::AllTools));
88 assert!(!specific_tool.covers(&Permission::AllTools));
89 assert!(specific_tool.covers(&Permission::Tool("search".into())));
90 }
91
92 #[test]
93 fn test_permission_display() {
94 assert_eq!(Permission::Tool("search".into()).to_string(), "tool:search");
95 assert_eq!(Permission::AllTools.to_string(), "tool:*");
96 assert_eq!(Permission::Agent("assistant".into()).to_string(), "agent:assistant");
97 assert_eq!(Permission::AllAgents.to_string(), "agent:*");
98 }
99}