1use super::contract::Contract;
2use super::type_graph::TypeRef;
3use super::validation_error::ContractValidationError;
4use crate::limits::Limits;
5use serde::{Deserialize, Serialize};
6
7pub const SOURCE_INFO_VERSION: u32 = 1;
8
9#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
12#[serde(deny_unknown_fields)]
13pub struct SourceInfo {
14 pub(crate) source_info_version: u32,
15 pub(crate) contract_id: String,
16 pub(crate) source_bundle_id: String,
17 pub(crate) sources: Vec<SourceFileInfo>,
18 #[serde(default)]
19 pub(crate) imports: Vec<SourceImportInfo>,
20 #[serde(default)]
21 pub(crate) declarations: Vec<SourceDeclaration>,
22 #[serde(default)]
23 pub(crate) field_labels: Vec<FieldLabelProvenance>,
24 #[serde(default)]
25 pub(crate) methods: Vec<SourceMethodInfo>,
26 #[serde(default)]
27 pub(crate) function_arguments: Vec<SourceFunctionArgumentInfo>,
28 #[serde(default)]
29 pub(crate) actors: Vec<SourceActorInfo>,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
33#[serde(deny_unknown_fields)]
34pub struct RawSourceInfo {
46 pub source_info_version: u32,
47 pub contract_id: String,
48 pub source_bundle_id: String,
49 pub sources: Vec<SourceFileInfo>,
50 #[serde(default)]
51 pub imports: Vec<SourceImportInfo>,
52 #[serde(default)]
53 pub declarations: Vec<SourceDeclaration>,
54 #[serde(default)]
55 pub field_labels: Vec<FieldLabelProvenance>,
56 #[serde(default)]
57 pub methods: Vec<SourceMethodInfo>,
58 #[serde(default)]
59 pub function_arguments: Vec<SourceFunctionArgumentInfo>,
60 #[serde(default)]
61 pub actors: Vec<SourceActorInfo>,
62}
63
64impl SourceInfo {
65 pub(crate) fn from_raw_unchecked(raw: RawSourceInfo) -> Self {
66 Self {
67 source_info_version: raw.source_info_version,
68 contract_id: raw.contract_id,
69 source_bundle_id: raw.source_bundle_id,
70 sources: raw.sources,
71 imports: raw.imports,
72 declarations: raw.declarations,
73 field_labels: raw.field_labels,
74 methods: raw.methods,
75 function_arguments: raw.function_arguments,
76 actors: raw.actors,
77 }
78 }
79
80 pub fn try_from_raw(
83 raw: RawSourceInfo,
84 contract: &Contract,
85 limits: &Limits,
86 ) -> Result<Self, ContractValidationError> {
87 let source_info = Self::from_raw_unchecked(raw);
88 source_info.validate(contract, limits)?;
89 Ok(source_info)
90 }
91
92 pub fn try_from_raw_with_context(
93 raw: RawSourceInfo,
94 contract: &Contract,
95 context: &crate::RuntimeContext,
96 ) -> Result<Self, ContractValidationError> {
97 let source_info = Self::from_raw_unchecked(raw);
98 let mut budget = context.budget();
99 source_info.validate_with_budget(contract, &mut budget)?;
100 Ok(source_info)
101 }
102
103 pub fn source_info_version(&self) -> u32 {
104 self.source_info_version
105 }
106
107 pub fn contract_id(&self) -> &str {
108 &self.contract_id
109 }
110
111 pub fn source_bundle_id(&self) -> &str {
112 &self.source_bundle_id
113 }
114
115 pub fn sources(&self) -> &[SourceFileInfo] {
116 &self.sources
117 }
118
119 pub fn imports(&self) -> &[SourceImportInfo] {
120 &self.imports
121 }
122
123 pub fn declarations(&self) -> &[SourceDeclaration] {
124 &self.declarations
125 }
126
127 pub fn field_labels(&self) -> &[FieldLabelProvenance] {
128 &self.field_labels
129 }
130
131 pub fn methods(&self) -> &[SourceMethodInfo] {
132 &self.methods
133 }
134
135 pub fn function_arguments(&self) -> &[SourceFunctionArgumentInfo] {
136 &self.function_arguments
137 }
138
139 pub fn actors(&self) -> &[SourceActorInfo] {
140 &self.actors
141 }
142
143 pub fn validate(
144 &self,
145 contract: &Contract,
146 limits: &Limits,
147 ) -> Result<(), ContractValidationError> {
148 crate::source::validate_source_info(self, contract, limits)
149 }
150
151 pub(crate) fn validate_with_budget(
152 &self,
153 contract: &Contract,
154 budget: &mut crate::budget::Budget<'_>,
155 ) -> Result<(), ContractValidationError> {
156 crate::source::validate_source_info_with_budget(self, contract, budget)
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
161#[serde(deny_unknown_fields)]
162pub struct SourceFileInfo {
163 pub name: String,
164 pub source: String,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
168#[serde(rename_all = "snake_case")]
169pub enum SourceImportKind {
170 Type,
171 Service,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
175#[serde(deny_unknown_fields)]
176pub struct SourceImportInfo {
177 pub from: String,
178 pub import: String,
179 pub to: String,
180 pub kind: SourceImportKind,
181}
182
183#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
184#[serde(deny_unknown_fields)]
185pub struct SourceDeclaration {
186 pub source: String,
187 pub name: String,
188 #[serde(rename = "type")]
189 pub ty: TypeRef,
190 #[serde(default, skip_serializing_if = "Vec::is_empty")]
191 pub docs: Vec<String>,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
195#[serde(deny_unknown_fields)]
196pub struct SourceActorInfo {
197 pub source: String,
198 #[serde(default, skip_serializing_if = "Vec::is_empty")]
199 pub docs: Vec<String>,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
203#[serde(deny_unknown_fields)]
204pub struct FieldLabelProvenance {
205 pub origin: SourceOrigin,
208 pub path: String,
210 pub container: TypeRef,
211 pub id: u32,
212 pub label: SourceLabel,
213 #[serde(default, skip_serializing_if = "Vec::is_empty")]
214 pub docs: Vec<String>,
215}
216
217#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
218#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
219pub enum SourceOrigin {
220 Declaration { source: String, name: String },
221 Actor { source: String },
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
225#[serde(deny_unknown_fields)]
226pub struct SourceMethodInfo {
227 pub origin: SourceOrigin,
228 pub path: String,
229 pub service: TypeRef,
230 pub name: String,
231 #[serde(default, skip_serializing_if = "Vec::is_empty")]
232 pub docs: Vec<String>,
233}
234
235#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
236#[serde(deny_unknown_fields)]
237pub struct SourceFunctionArgumentInfo {
238 pub origin: SourceOrigin,
239 pub path: String,
240 pub function: TypeRef,
241 pub direction: SourceFunctionArgumentDirection,
242 pub position: u32,
243 pub name: String,
244}
245
246#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
247#[serde(rename_all = "snake_case")]
248pub enum SourceFunctionArgumentDirection {
249 Argument,
250 Result,
251}
252
253#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
256#[serde(tag = "kind", rename_all = "snake_case", deny_unknown_fields)]
257pub enum SourceLabel {
258 Named { name: String },
259 Numeric,
260 Positional,
261}