Skip to main content

callisto_model/
dependency.rs

1use std::path::PathBuf;
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::{PackageId, Version, VersionReq};
7
8/// Dependency kind (section in manifest).
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, JsonSchema)]
10#[serde(rename_all = "camelCase")]
11pub enum DepKind {
12    Runtime,
13    Dev,
14    Peer,
15    Optional,
16    Build,
17}
18
19/// Dependency specification requirement.
20#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
21#[serde(rename_all = "camelCase")]
22pub enum DepSpec {
23    Exact(Version),
24    Range(VersionReq, String),
25    Workspace(WorkspaceKind),
26    Catalog(Option<String>),
27    CargoBare(Version),
28    Opaque(String),
29}
30
31impl DepSpec {
32    pub fn render(&self) -> String {
33        match self {
34            DepSpec::Exact(v) => v.render().to_string(),
35            DepSpec::Range(_, raw) => raw.clone(),
36            DepSpec::Workspace(kind) => match kind {
37                WorkspaceKind::Pnpm | WorkspaceKind::Yarn | WorkspaceKind::Npm => "workspace:*".to_string(),
38            },
39            DepSpec::Catalog(opt) => match opt {
40                Some(name) => format!("catalog:{name}"),
41                None => "catalog:".to_string(),
42            },
43            DepSpec::CargoBare(v) => v.render().to_string(),
44            DepSpec::Opaque(raw) => raw.clone(),
45        }
46    }
47}
48
49/// Ecosystem workspace protocol type.
50#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
51#[serde(rename_all = "lowercase")]
52pub enum WorkspaceKind {
53    Pnpm,
54    Yarn,
55    Npm,
56}
57
58/// Evaluation of whether a version specification covers a candidate version.
59#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
60#[serde(rename_all = "camelCase")]
61pub enum Coverage {
62    Covers,
63    DoesNotCover,
64    Unknown,
65}
66
67/// Dependency entry read directly from a manifest.
68#[derive(Clone, Debug, PartialEq, Eq)]
69pub struct DependencyEntry {
70    pub name: String,
71    pub kind: DepKind,
72    pub spec: DepSpec,
73    pub inherited: bool,
74}
75
76/// Resolved dependency edge between two packages in the workspace graph.
77#[derive(Clone, Debug, PartialEq, Eq)]
78pub struct DepEdge {
79    pub from: PackageId,
80    pub to: PackageId,
81    pub kind: DepKind,
82    pub spec: DepSpec,
83    pub from_manifest: PathBuf,
84    pub inherited: bool,
85}