use std::any::Any;
use std::collections::HashMap;
use tower_lsp_server::ls_types::Range;
pub use deps_core::parser::DependencySource;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParsedDependency {
pub name: String,
pub name_range: Range,
pub version_req: Option<String>,
pub version_range: Option<Range>,
pub features: Vec<String>,
pub features_range: Option<Range>,
pub source: DependencySource,
pub section: DependencySection,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DependencySection {
Dependencies,
DevDependencies,
BuildDependencies,
WorkspaceDependencies,
}
#[derive(Debug, Clone)]
pub struct CargoVersion {
pub num: String,
pub yanked: bool,
pub features: HashMap<String, Vec<String>>,
}
#[derive(Debug, Clone)]
pub struct CrateInfo {
pub name: String,
pub description: Option<String>,
pub repository: Option<String>,
pub documentation: Option<String>,
pub max_version: String,
}
impl deps_core::Dependency for ParsedDependency {
fn name(&self) -> &str {
&self.name
}
fn name_range(&self) -> Range {
self.name_range
}
fn version_requirement(&self) -> Option<&str> {
self.version_req.as_deref()
}
fn version_range(&self) -> Option<Range> {
self.version_range
}
fn source(&self) -> deps_core::parser::DependencySource {
self.source.clone()
}
fn features(&self) -> &[String] {
&self.features
}
fn features_range(&self) -> Option<Range> {
self.features_range
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl deps_core::Version for CargoVersion {
fn version_string(&self) -> &str {
&self.num
}
fn is_yanked(&self) -> bool {
self.yanked
}
fn features(&self) -> Vec<String> {
self.features.keys().cloned().collect()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl deps_core::Metadata for CrateInfo {
fn name(&self) -> &str {
&self.name
}
fn description(&self) -> Option<&str> {
self.description.as_deref()
}
fn repository(&self) -> Option<&str> {
self.repository.as_deref()
}
fn documentation(&self) -> Option<&str> {
self.documentation.as_deref()
}
fn latest_version(&self) -> &str {
&self.max_version
}
fn as_any(&self) -> &dyn Any {
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dependency_source_variants() {
assert!(matches!(
DependencySource::Registry,
DependencySource::Registry
));
assert!(matches!(
DependencySource::Git {
url: "u".into(),
rev: None
},
DependencySource::Git { .. }
));
assert!(matches!(
DependencySource::Path { path: "p".into() },
DependencySource::Path { .. }
));
assert!(matches!(
DependencySource::Workspace,
DependencySource::Workspace
));
}
#[test]
fn test_dependency_section_variants() {
let deps = DependencySection::Dependencies;
let dev_deps = DependencySection::DevDependencies;
let build_deps = DependencySection::BuildDependencies;
let workspace_deps = DependencySection::WorkspaceDependencies;
assert!(matches!(deps, DependencySection::Dependencies));
assert!(matches!(dev_deps, DependencySection::DevDependencies));
assert!(matches!(build_deps, DependencySection::BuildDependencies));
assert!(matches!(
workspace_deps,
DependencySection::WorkspaceDependencies
));
}
#[test]
fn test_cargo_version_creation() {
let version = CargoVersion {
num: "1.0.0".into(),
yanked: false,
features: HashMap::new(),
};
assert_eq!(version.num, "1.0.0");
assert!(!version.yanked);
assert!(version.features.is_empty());
}
}