Skip to main content

deps_gradle/
types.rs

1//! Domain types for Gradle dependencies.
2
3use std::any::Any;
4use tower_lsp_server::ls_types::Range;
5
6pub use deps_maven::MavenVersion as GradleVersion;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct GradleDependency {
10    pub group_id: String,
11    pub artifact_id: String,
12    /// Canonical identifier: "{groupId}:{artifactId}"
13    pub name: deps_core::PackageName,
14    pub name_range: Range,
15    pub version_req: Option<deps_core::VersionReq>,
16    pub version_range: Option<Range>,
17    /// Gradle configuration (e.g. "implementation", "api", "testImplementation")
18    pub configuration: String,
19}
20
21impl deps_core::Dependency for GradleDependency {
22    fn name(&self) -> &deps_core::PackageName {
23        &self.name
24    }
25
26    fn name_range(&self) -> Range {
27        self.name_range
28    }
29
30    fn version_requirement(&self) -> Option<&deps_core::VersionReq> {
31        self.version_req.as_ref()
32    }
33
34    fn version_range(&self) -> Option<Range> {
35        self.version_range
36    }
37
38    fn source(&self) -> deps_core::parser::DependencySource {
39        deps_core::parser::DependencySource::Registry
40    }
41
42    fn features(&self) -> &[String] {
43        &[]
44    }
45
46    fn as_any(&self) -> &dyn Any {
47        self
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use std::assert_matches;
55    use tower_lsp_server::ls_types::Position;
56
57    fn test_dep() -> GradleDependency {
58        GradleDependency {
59            group_id: "org.springframework.boot".into(),
60            artifact_id: "spring-boot-starter".into(),
61            name: "org.springframework.boot:spring-boot-starter".into(),
62            name_range: Range::new(Position::new(5, 4), Position::new(5, 30)),
63            version_req: Some("3.2.0".into()),
64            version_range: Some(Range::new(Position::new(5, 35), Position::new(5, 40))),
65            configuration: "implementation".into(),
66        }
67    }
68
69    #[test]
70    fn test_dependency_trait() {
71        use deps_core::Dependency;
72
73        let dep = test_dep();
74        assert_eq!(dep.name(), "org.springframework.boot:spring-boot-starter");
75        assert_eq!(
76            dep.version_requirement().map(deps_core::VersionReq::as_str),
77            Some("3.2.0")
78        );
79        assert!(dep.features().is_empty());
80        assert!(dep.as_any().is::<GradleDependency>());
81        assert_matches!(dep.source(), deps_core::parser::DependencySource::Registry);
82    }
83
84    #[test]
85    fn test_dependency_info_trait() {
86        use deps_core::Dependency;
87
88        let dep = test_dep();
89        assert_eq!(dep.name(), "org.springframework.boot:spring-boot-starter");
90        assert!(dep.version_range().is_some());
91        assert_matches!(dep.source(), deps_core::parser::DependencySource::Registry);
92    }
93
94    #[test]
95    fn test_dependency_without_version() {
96        use deps_core::Dependency;
97
98        let dep = GradleDependency {
99            group_id: "com.example".into(),
100            artifact_id: "test".into(),
101            name: "com.example:test".into(),
102            name_range: Range::default(),
103            version_req: None,
104            version_range: None,
105            configuration: "api".into(),
106        };
107        assert!(dep.version_requirement().is_none());
108        assert!(dep.version_range().is_none());
109    }
110
111    /// `GradleVersion` is a re-export of `deps_maven::MavenVersion` (see the `pub use` at
112    /// the top of this module), not a type this crate defines — so `published_at` is wired
113    /// by construction rather than by anything `deps-gradle` implements itself. This test
114    /// exists so a future change that breaks the re-export (e.g. swapping it for a
115    /// gradle-specific newtype) fails loudly here instead of silently losing freshness data.
116    #[test]
117    fn test_gradle_version_published_at_is_wired_through_the_maven_reexport() {
118        use deps_core::Version;
119
120        let published = deps_core::PublishTime::parse_rfc3339("2026-07-18T23:05:13Z").unwrap();
121        let version = GradleVersion {
122            version: "3.2.0".into(),
123            published_at: Some(published),
124        };
125
126        assert_eq!(version.published_at(), Some(published));
127    }
128}