1pub mod error;
2pub mod http_client;
3pub mod openapi;
4pub mod server;
5pub mod tool;
6pub mod tool_generator;
7pub mod tool_registry;
8
9pub use error::{CliError, OpenApiError, ToolCallError};
10pub use http_client::{HttpClient, HttpResponse};
11pub use openapi::OpenApiSpec;
12pub use openapi::OpenApiSpecLocation;
13pub use tool::ToolMetadata;
14pub use tool_generator::{ExtractedParameters, RequestConfig, ToolGenerator};
15pub use tool_registry::{ToolRegistry, ToolRegistryStats};
16
17pub(crate) fn find_similar_strings(unknown: &str, known_strings: &[&str]) -> Vec<String> {
20 use strsim::jaro;
21
22 let mut candidates = Vec::new();
23 for string in known_strings {
24 let confidence = jaro(unknown, string);
25 if confidence > 0.7 {
26 candidates.push((confidence, string.to_string()));
27 }
28 }
29
30 candidates.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap());
32 candidates.into_iter().map(|(_, name)| name).collect()
33}
34
35pub(crate) fn normalize_tag(tag: &str) -> String {
38 use heck::ToKebabCase;
39 tag.to_kebab_case()
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_find_similar_strings() {
48 let known = vec!["page_size", "user_id", "status"];
50 let suggestions = find_similar_strings("page_sixe", &known);
51 assert_eq!(suggestions, vec!["page_size"]);
52
53 let suggestions = find_similar_strings("xyz123", &known);
55 assert!(suggestions.is_empty());
56
57 let known = vec!["limit", "offset"];
59 let suggestions = find_similar_strings("lmiit", &known);
60 assert_eq!(suggestions, vec!["limit"]);
61
62 let known = vec!["project_id", "merge_request_id"];
64 let suggestions = find_similar_strings("projct_id", &known);
65 assert_eq!(suggestions, vec!["project_id"]);
66
67 let known = vec!["name", "email"];
69 let suggestions = find_similar_strings("namee", &known);
70 assert_eq!(suggestions, vec!["name"]);
71 }
72
73 #[test]
74 fn test_normalize_tag() {
75 assert_eq!(normalize_tag("userManagement"), "user-management");
77 assert_eq!(normalize_tag("getUsers"), "get-users");
78
79 assert_eq!(normalize_tag("UserManagement"), "user-management");
81 assert_eq!(normalize_tag("APIKey"), "api-key");
82
83 assert_eq!(normalize_tag("user_management"), "user-management");
85 assert_eq!(normalize_tag("get_users"), "get-users");
86
87 assert_eq!(normalize_tag("USER_MANAGEMENT"), "user-management");
89 assert_eq!(normalize_tag("API_KEY"), "api-key");
90
91 assert_eq!(normalize_tag("user-management"), "user-management");
93 assert_eq!(normalize_tag("api-key"), "api-key");
94
95 assert_eq!(normalize_tag("users"), "users");
97 assert_eq!(normalize_tag("API"), "api");
98
99 assert_eq!(normalize_tag(""), "");
101
102 assert_eq!(normalize_tag("XMLHttpRequest"), "xml-http-request");
104 assert_eq!(normalize_tag("HTTPSConnection"), "https-connection");
105
106 assert_eq!(normalize_tag("user management"), "user-management");
108 assert_eq!(normalize_tag(" user "), "user"); assert_eq!(normalize_tag("user__management"), "user-management");
112 assert_eq!(normalize_tag("user---management"), "user-management");
113
114 assert_eq!(normalize_tag("user123Management"), "user123-management");
116 assert_eq!(normalize_tag("user@management"), "user-management"); assert_eq!(normalize_tag("v2ApiEndpoint"), "v2-api-endpoint");
120 assert_eq!(normalize_tag("HTML5Parser"), "html5-parser");
121 }
122}