Skip to content

Commit bf17a76

Browse files
authored
resolve parameters before codegen (#524)
1 parent b921f74 commit bf17a76

File tree

2 files changed

+45
-27
lines changed

2 files changed

+45
-27
lines changed

services/autorust/codegen/src/codegen_operations.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use heck::SnakeCase;
1414
use indexmap::IndexMap;
1515
use proc_macro2::TokenStream;
1616
use quote::quote;
17-
use std::{collections::HashSet, path::Path};
17+
use std::collections::HashSet;
1818

1919
fn error_variant(operation: &WebOperation) -> Result<TokenStream, Error> {
2020
let function = operation.rust_function_name().to_camel_case();
@@ -117,16 +117,16 @@ fn create_function(cg: &CodeGen, operation: &WebOperation) -> Result<TokenStream
117117

118118
let fpath = format!("{{}}{}", &format_path(&operation.path));
119119

120-
let parameters: Vec<Parameter> = cg.spec.resolve_parameters(&operation.doc_file, &operation.parameters)?;
120+
let parameters = &operation.parameters;
121121
let param_names: HashSet<_> = parameters.iter().map(|p| p.name.as_str()).collect();
122122
let has_param_api_version = param_names.contains("api-version");
123123
let mut skip = HashSet::new();
124124
if cg.spec.api_version().is_some() {
125125
skip.insert("api-version");
126126
}
127-
let parameters: Vec<_> = parameters.into_iter().filter(|p| !skip.contains(p.name.as_str())).collect();
127+
let parameters: Vec<_> = parameters.iter().filter(|p| !skip.contains(p.name.as_str())).collect();
128128

129-
let fparams = create_function_params(cg, &operation.doc_file, &parameters)?;
129+
let fparams = create_function_params(&parameters)?;
130130

131131
// see if there is a body parameter
132132
// let fresponse = create_function_return(operation_verb)?;
@@ -550,7 +550,7 @@ fn format_path(path: &str) -> String {
550550
PARAM_RE.replace_all(path, "{}").to_string()
551551
}
552552

553-
fn create_function_params(_cg: &CodeGen, _doc_file: &Path, parameters: &[Parameter]) -> Result<TokenStream, Error> {
553+
fn create_function_params(parameters: &[&Parameter]) -> Result<TokenStream, Error> {
554554
let mut params: Vec<TokenStream> = Vec::new();
555555
for param in parameters {
556556
let name = get_param_name(param)?;

services/autorust/codegen/src/spec.rs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl Spec {
167167
}
168168

169169
/// Resolve a reference or schema to a resolved schema
170-
pub fn resolve_schema<P: AsRef<Path>>(&self, doc_file: P, ref_or_schema: &ReferenceOr<Schema>) -> Result<ResolvedSchema> {
170+
fn resolve_schema<P: AsRef<Path>>(&self, doc_file: P, ref_or_schema: &ReferenceOr<Schema>) -> Result<ResolvedSchema> {
171171
match ref_or_schema {
172172
ReferenceOr::Item(schema) => Ok(ResolvedSchema {
173173
ref_key: None,
@@ -177,15 +177,6 @@ impl Spec {
177177
}
178178
}
179179

180-
/// Resolve a collection of references or schemas to a collection of resolved schemas
181-
pub fn resolve_schemas<P: AsRef<Path>>(&self, doc_file: P, ref_or_schemas: &[ReferenceOr<Schema>]) -> Result<Vec<ResolvedSchema>> {
182-
let mut resolved = Vec::new();
183-
for schema in ref_or_schemas {
184-
resolved.push(self.resolve_schema(&doc_file, schema)?);
185-
}
186-
Ok(resolved)
187-
}
188-
189180
/// Resolve a collection of references or schemas to a collection of resolved schemas
190181
pub fn resolve_schema_map<P: AsRef<Path>>(
191182
&self,
@@ -218,14 +209,14 @@ impl Spec {
218209
Ok(resolved)
219210
}
220211

221-
pub fn resolve_parameter(&self, doc_file: &Path, parameter: &ReferenceOr<Parameter>) -> Result<Parameter> {
212+
fn resolve_parameter(&self, doc_file: &Path, parameter: &ReferenceOr<Parameter>) -> Result<Parameter> {
222213
match parameter {
223214
ReferenceOr::Item(param) => Ok(param.clone()),
224215
ReferenceOr::Reference { reference, .. } => self.resolve_parameter_ref(doc_file, reference.clone()),
225216
}
226217
}
227218

228-
pub fn resolve_parameters(&self, doc_file: &Path, parameters: &[ReferenceOr<Parameter>]) -> Result<Vec<Parameter>> {
219+
fn resolve_parameters(&self, doc_file: &Path, parameters: &[ReferenceOr<Parameter>]) -> Result<Vec<Parameter>> {
229220
let mut resolved = Vec::new();
230221
for param in parameters {
231222
resolved.push(self.resolve_parameter(doc_file, param)?);
@@ -234,18 +225,37 @@ impl Spec {
234225
}
235226

236227
// only operations from listed input files
237-
pub fn operations(&self) -> Result<Vec<WebOperation>> {
238-
let mut operations: Vec<WebOperation> = Vec::new();
228+
fn operations_unresolved(&self) -> Result<Vec<WebOperationUnresolved>> {
229+
let mut operations: Vec<WebOperationUnresolved> = Vec::new();
239230
for (doc_file, doc) in self.docs() {
240231
if self.is_input_file(&doc_file) {
241232
let paths = self.resolve_path_map(doc_file, doc.paths())?;
242233
for (path, item) in &paths {
243-
operations.extend(path_operations(doc_file, path, item))
234+
operations.extend(path_operations_unresolved(doc_file, path, item))
244235
}
245236
}
246237
}
247238
Ok(operations)
248239
}
240+
241+
// only operations from listed input files
242+
pub fn operations(&self) -> Result<Vec<WebOperation>> {
243+
self.operations_unresolved()?
244+
.into_iter()
245+
.map({
246+
|op| {
247+
Ok(WebOperation {
248+
id: op.id,
249+
path: op.path,
250+
verb: op.verb,
251+
parameters: self.resolve_parameters(&op.doc_file, &op.parameters)?,
252+
responses: op.responses,
253+
examples: op.examples,
254+
})
255+
}
256+
})
257+
.collect()
258+
}
249259
}
250260

251261
type Result<T, E = Error> = std::result::Result<T, E>;
@@ -330,7 +340,7 @@ pub mod openapi {
330340
match item {
331341
ReferenceOr::Reference { reference, .. } => list.push(TypedReference::PathItem(reference.clone())),
332342
ReferenceOr::Item(item) => {
333-
for operation in path_operations(&doc_file, path, item) {
343+
for operation in path_operations_unresolved(&doc_file, path, item) {
334344
// parameters
335345
for param in &operation.parameters {
336346
match param {
@@ -386,7 +396,8 @@ pub mod openapi {
386396
}
387397
}
388398

389-
pub struct WebOperation {
399+
// contains unresolved parameters
400+
struct WebOperationUnresolved {
390401
pub doc_file: PathBuf,
391402
pub id: Option<String>,
392403
pub path: String,
@@ -396,6 +407,16 @@ pub struct WebOperation {
396407
pub examples: MsExamples,
397408
}
398409

410+
// contains resolved parameters
411+
pub struct WebOperation {
412+
pub id: Option<String>,
413+
pub path: String,
414+
pub verb: WebVerb,
415+
pub parameters: Vec<Parameter>,
416+
pub responses: IndexMap<StatusCode, Response>,
417+
pub examples: MsExamples,
418+
}
419+
399420
impl WebOperation {
400421
pub fn rust_module_name(&self) -> Option<String> {
401422
match &self.id {
@@ -462,7 +483,7 @@ struct OperationVerb<'a> {
462483
pub verb: WebVerb,
463484
}
464485

465-
pub fn path_operations<P: AsRef<Path>>(doc_file: P, path: &str, item: &PathItem) -> Vec<WebOperation> {
486+
fn path_operations_unresolved<P: AsRef<Path>>(doc_file: P, path: &str, item: &PathItem) -> Vec<WebOperationUnresolved> {
466487
vec![
467488
OperationVerb {
468489
operation: item.get.as_ref(),
@@ -498,7 +519,7 @@ pub fn path_operations<P: AsRef<Path>>(doc_file: P, path: &str, item: &PathItem)
498519
Some(op) => {
499520
let mut parameters = item.parameters.clone();
500521
parameters.append(&mut op.parameters.clone());
501-
Some(WebOperation {
522+
Some(WebOperationUnresolved {
502523
doc_file: doc_file.as_ref().to_path_buf(),
503524
id: op.operation_id.clone(),
504525
path: path.to_string(),
@@ -588,7 +609,6 @@ mod tests {
588609
#[test]
589610
fn test_function_name_from_operation_id() {
590611
let operation = WebOperation {
591-
doc_file: PathBuf::from(""),
592612
id: Some("PrivateClouds_CreateOrUpdate".to_owned()),
593613
path: "/horse".to_owned(),
594614
verb: WebVerb::Get,
@@ -603,7 +623,6 @@ mod tests {
603623
#[test]
604624
fn test_function_name_from_verb_and_path() {
605625
let operation = WebOperation {
606-
doc_file: PathBuf::from(""),
607626
id: None,
608627
path: "/horse".to_owned(),
609628
verb: WebVerb::Get,
@@ -618,7 +637,6 @@ mod tests {
618637
#[test]
619638
fn test_function_name_with_no_module_name() {
620639
let operation = WebOperation {
621-
doc_file: PathBuf::from(""),
622640
id: Some("PerformConnectivityCheck".to_owned()),
623641
path: "/horse".to_owned(),
624642
verb: WebVerb::Put,

0 commit comments

Comments
 (0)