miden_project/ast/
dependency.rs1use super::{parsing::SetSourceId, *};
2use crate::{Linkage, SourceId, Span, Uri, VersionRequirement};
3
4#[derive(Debug, Clone)]
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
8pub struct DependencySpec {
9 #[cfg_attr(feature = "serde", serde(default, skip))]
11 pub name: Span<Arc<str>>,
12 #[cfg_attr(
14 feature = "serde",
15 serde(rename = "version", alias = "digest", skip_serializing_if = "Option::is_none")
16 )]
17 pub version_or_digest: Option<VersionRequirement>,
18 #[cfg_attr(
20 feature = "serde",
21 serde(default, skip_serializing_if = "does_not_inherit_from_workspace")
22 )]
23 pub workspace: bool,
24 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
26 pub path: Option<Span<Uri>>,
27 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
30 pub git: Option<Span<Uri>>,
31 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
37 pub branch: Option<Span<Arc<str>>>,
38 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
44 pub rev: Option<Span<Arc<str>>>,
45 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))]
47 pub linkage: Option<Span<Linkage>>,
48}
49
50#[inline(always)]
51fn does_not_inherit_from_workspace(is_workspace_dependency: &bool) -> bool {
52 !(*is_workspace_dependency)
53}
54
55impl DependencySpec {
56 pub fn version(&self) -> Option<&VersionRequirement> {
58 self.version_or_digest.as_ref()
59 }
60
61 pub fn inherits_workspace_version(&self) -> bool {
63 self.workspace
64 }
65
66 pub fn is_host_resolved(&self) -> bool {
68 self.git.is_none() && self.path.is_none()
69 }
70
71 pub fn is_path(&self) -> bool {
73 self.path.is_some() && self.git.is_none()
74 }
75
76 pub fn is_git(&self) -> bool {
78 self.git.is_some()
79 }
80}
81
82impl SetSourceId for DependencySpec {
83 fn set_source_id(&mut self, source_id: SourceId) {
84 self.name.set_source_id(source_id);
85 if let Some(version_or_digest) = self.version_or_digest.as_mut() {
86 version_or_digest.set_source_id(source_id);
87 }
88
89 if let Some(path) = self.path.as_mut() {
90 path.set_source_id(source_id);
91 }
92
93 if let Some(git) = self.git.as_mut() {
94 git.set_source_id(source_id);
95 }
96
97 if let Some(branch) = self.branch.as_mut() {
98 branch.set_source_id(source_id);
99 }
100
101 if let Some(rev) = self.rev.as_mut() {
102 rev.set_source_id(source_id);
103 }
104 }
105}
106
107#[cfg(feature = "serde")]
108pub use self::serialization::deserialize_dependency_map;
109
110#[cfg(feature = "serde")]
111mod serialization {
112 use alloc::sync::Arc;
113
114 use miden_assembly_syntax::debuginfo::Span;
115 use serde::de::{MapAccess, Visitor};
116
117 use super::DependencySpec;
118 use crate::Map;
119
120 struct DependencyMapVisitor;
121
122 impl<'de> Visitor<'de> for DependencyMapVisitor {
123 type Value = Map<Span<Arc<str>>, Span<DependencySpec>>;
124
125 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
126 formatter.write_str("a dependency map")
127 }
128
129 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
130 where
131 M: MapAccess<'de>,
132 {
133 let mut map = Self::Value::default();
134
135 while let Some((key, mut value)) =
136 access.next_entry::<Span<Arc<str>>, Span<DependencySpec>>()?
137 {
138 value.name = key.clone();
139 map.insert(key, value);
140 }
141
142 Ok(map)
143 }
144 }
145
146 #[allow(clippy::type_complexity)]
147 pub fn deserialize_dependency_map<'de, D>(
148 deserializer: D,
149 ) -> Result<Map<Span<Arc<str>>, Span<DependencySpec>>, D::Error>
150 where
151 D: serde::Deserializer<'de>,
152 {
153 deserializer.deserialize_map(DependencyMapVisitor)
154 }
155}