1use deps_core::lsp_helpers::EcosystemFormatter;
2
3pub struct GoFormatter;
10
11impl EcosystemFormatter for GoFormatter {
12 fn format_version_for_code_action(&self, version: &str) -> String {
13 version.to_string()
16 }
17
18 fn package_url(&self, name: &str) -> String {
19 let encoded = name.replace('@', "%40").replace(' ', "%20");
22 format!("https://pkg.go.dev/{encoded}")
23 }
24
25 fn version_satisfies_requirement(&self, version: &str, requirement: &str) -> bool {
26 if version == requirement {
33 return true;
34 }
35
36 if let Some(suffix) = version.strip_prefix(requirement) {
40 return suffix.is_empty()
41 || suffix.starts_with('.')
42 || suffix.starts_with('-')
43 || suffix.starts_with('+');
44 }
45
46 false
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[test]
55 fn test_format_version_for_code_action() {
56 let formatter = GoFormatter;
57
58 assert_eq!(formatter.format_version_for_code_action("v1.2.3"), "v1.2.3");
60
61 assert_eq!(
63 formatter.format_version_for_code_action("v0.0.0-20191109021931-daa7c04131f5"),
64 "v0.0.0-20191109021931-daa7c04131f5"
65 );
66
67 assert_eq!(
69 formatter.format_version_for_code_action("v2.0.0+incompatible"),
70 "v2.0.0+incompatible"
71 );
72 }
73
74 #[test]
75 fn test_package_url() {
76 let formatter = GoFormatter;
77
78 assert_eq!(
80 formatter.package_url("github.com/gin-gonic/gin"),
81 "https://pkg.go.dev/github.com/gin-gonic/gin"
82 );
83
84 assert_eq!(
86 formatter.package_url("github.com/go-redis/redis/v8"),
87 "https://pkg.go.dev/github.com/go-redis/redis/v8"
88 );
89
90 assert_eq!(formatter.package_url("fmt"), "https://pkg.go.dev/fmt");
92
93 assert_eq!(
95 formatter.package_url("github.com/user@org/package"),
96 "https://pkg.go.dev/github.com/user%40org/package"
97 );
98
99 assert_eq!(
101 formatter.package_url("github.com/user/pkg name"),
102 "https://pkg.go.dev/github.com/user/pkg%20name"
103 );
104 }
105
106 #[test]
107 fn test_version_satisfies_requirement_exact_match() {
108 let formatter = GoFormatter;
109
110 assert!(formatter.version_satisfies_requirement("v1.2.3", "v1.2.3"));
112 assert!(formatter.version_satisfies_requirement("v0.1.0", "v0.1.0"));
113 }
114
115 #[test]
116 fn test_version_satisfies_requirement_pseudo_version() {
117 let formatter = GoFormatter;
118
119 assert!(
121 formatter.version_satisfies_requirement("v0.0.0-20191109021931-daa7c04131f5", "v0.0.0")
122 );
123
124 assert!(formatter.version_satisfies_requirement(
126 "v0.0.0-20191109021931-daa7c04131f5",
127 "v0.0.0-20191109021931-daa7c04131f5"
128 ));
129 }
130
131 #[test]
132 fn test_version_satisfies_requirement_incompatible() {
133 let formatter = GoFormatter;
134
135 assert!(formatter.version_satisfies_requirement("v2.0.0+incompatible", "v2.0.0"));
137
138 assert!(
140 formatter.version_satisfies_requirement("v2.0.0+incompatible", "v2.0.0+incompatible")
141 );
142 }
143
144 #[test]
145 fn test_version_does_not_satisfy_requirement() {
146 let formatter = GoFormatter;
147
148 assert!(!formatter.version_satisfies_requirement("v1.2.3", "v1.2.4"));
150 assert!(!formatter.version_satisfies_requirement("v2.0.0", "v1.0.0"));
151
152 assert!(!formatter.version_satisfies_requirement("v1.2.3", "v1.2.3.4"));
154 }
155
156 #[test]
157 fn test_version_satisfies_requirement_prefix_scenarios() {
158 let formatter = GoFormatter;
159
160 assert!(!formatter.version_satisfies_requirement("v1.2", "v1.2.3"));
162
163 assert!(formatter.version_satisfies_requirement("v1.2.3", "v1.2"));
165
166 assert!(!formatter.version_satisfies_requirement("v1.2.30", "v1.2.3"));
168
169 assert!(formatter.version_satisfies_requirement("v1.2.3.1", "v1.2.3"));
171 }
172}