1use agent_uri::{CapabilityPath, TrustRoot};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum MatchMode {
8 Exact,
10 Prefix,
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct Query {
20 trust_root: TrustRoot,
21 capability_path: CapabilityPath,
22 match_mode: MatchMode,
23}
24
25impl Query {
26 #[must_use]
28 pub const fn exact(trust_root: TrustRoot, capability_path: CapabilityPath) -> Self {
29 Self {
30 trust_root,
31 capability_path,
32 match_mode: MatchMode::Exact,
33 }
34 }
35
36 #[must_use]
38 pub const fn prefix(trust_root: TrustRoot, capability_path: CapabilityPath) -> Self {
39 Self {
40 trust_root,
41 capability_path,
42 match_mode: MatchMode::Prefix,
43 }
44 }
45
46 #[must_use]
48 pub const fn trust_root(&self) -> &TrustRoot {
49 &self.trust_root
50 }
51
52 #[must_use]
54 pub const fn capability_path(&self) -> &CapabilityPath {
55 &self.capability_path
56 }
57
58 #[must_use]
60 pub const fn match_mode(&self) -> MatchMode {
61 self.match_mode
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 fn parts() -> (TrustRoot, CapabilityPath) {
70 (
71 TrustRoot::parse("anthropic.com").unwrap(),
72 CapabilityPath::parse("assistant/chat").unwrap(),
73 )
74 }
75
76 #[test]
77 fn exact_query_records_its_mode() {
78 let (tr, path) = parts();
79 let q = Query::exact(tr, path);
80 assert_eq!(q.match_mode(), MatchMode::Exact);
81 assert_eq!(q.trust_root().as_str(), "anthropic.com");
82 assert_eq!(q.capability_path().as_str(), "assistant/chat");
83 }
84
85 #[test]
86 fn prefix_query_records_its_mode() {
87 let (tr, path) = parts();
88 let q = Query::prefix(tr, path);
89 assert_eq!(q.match_mode(), MatchMode::Prefix);
90 }
91
92 #[test]
93 fn queries_differing_only_in_mode_are_not_equal() {
94 let (tr, path) = parts();
95 assert_ne!(
96 Query::exact(tr.clone(), path.clone()),
97 Query::prefix(tr, path)
98 );
99 }
100}