Skip to main content

callisto_graph/
resolver.rs

1use std::collections::{BTreeMap, HashSet};
2
3use callisto_model::{DepEdge, Diagnostic, Package, PackageId};
4
5use crate::error::GraphError;
6use crate::identity::IdentityIndex;
7use crate::toposort::toposort_impl;
8
9pub use callisto_model::DependencyResolver;
10
11pub trait DependencyResolverExt: DependencyResolver {
12    fn toposort(&self, subset: &HashSet<PackageId>) -> Result<Vec<PackageId>, GraphError> {
13        let all_pkg_ids: Vec<PackageId> = self.packages().map(|p| p.id.clone()).collect();
14        toposort_impl(subset, &all_pkg_ids, |id| {
15            self.dependencies_of(id)
16                .map(|e| (e.to.clone(), e.kind))
17                .collect()
18        })
19    }
20}
21
22impl<T: DependencyResolver + ?Sized> DependencyResolverExt for T {}
23
24pub struct ManifestWalkResolver {
25    pub(crate) packages: BTreeMap<PackageId, Package>,
26    pub(crate) edges: Vec<DepEdge>,
27    pub(crate) out_index: BTreeMap<PackageId, Vec<usize>>,
28    pub(crate) in_index: BTreeMap<PackageId, Vec<usize>>,
29    pub(crate) index: IdentityIndex,
30    pub(crate) diagnostics: Vec<Diagnostic>,
31}
32
33impl ManifestWalkResolver {
34    pub fn diagnostics(&self) -> &[Diagnostic] {
35        &self.diagnostics
36    }
37
38    pub fn identity(&self) -> &IdentityIndex {
39        &self.index
40    }
41
42    pub fn get(&self, id: &PackageId) -> Option<&Package> {
43        self.packages.get(id)
44    }
45
46    pub fn edges(&self) -> &[DepEdge] {
47        &self.edges
48    }
49}
50
51impl DependencyResolver for ManifestWalkResolver {
52    fn packages(&self) -> impl Iterator<Item = &Package> {
53        self.packages.values()
54    }
55
56    fn dependencies_of(&self, id: &PackageId) -> impl Iterator<Item = &DepEdge> {
57        let empty = Vec::new();
58        let indices = self.out_index.get(id).unwrap_or(&empty);
59        let mut result = Vec::new();
60        for &idx in indices {
61            result.push(&self.edges[idx]);
62        }
63        result.into_iter()
64    }
65
66    fn dependents_of(&self, id: &PackageId) -> impl Iterator<Item = &DepEdge> {
67        let empty = Vec::new();
68        let indices = self.in_index.get(id).unwrap_or(&empty);
69        let mut result = Vec::new();
70        for &idx in indices {
71            result.push(&self.edges[idx]);
72        }
73        result.into_iter()
74    }
75
76    fn diagnostics(&self) -> &[Diagnostic] {
77        &self.diagnostics
78    }
79}