From 790ef589ed1b1878b0b8eea6006bcaa4cde26e23 Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Wed, 17 Nov 2021 22:07:49 -0600 Subject: [PATCH 1/4] resolve parameters --- .../codegen/src/codegen_operations.rs | 10 +-- services/autorust/codegen/src/spec.rs | 64 ++++++++++++------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/services/autorust/codegen/src/codegen_operations.rs b/services/autorust/codegen/src/codegen_operations.rs index f1587d7ba2..70746022ba 100644 --- a/services/autorust/codegen/src/codegen_operations.rs +++ b/services/autorust/codegen/src/codegen_operations.rs @@ -14,7 +14,7 @@ use heck::SnakeCase; use indexmap::IndexMap; use proc_macro2::TokenStream; use quote::quote; -use std::{collections::HashSet, path::Path}; +use std::collections::HashSet; fn error_variant(operation: &WebOperation) -> Result { let function = operation.rust_function_name().to_camel_case(); @@ -117,16 +117,16 @@ fn create_function(cg: &CodeGen, operation: &WebOperation) -> Result = cg.spec.resolve_parameters(&operation.doc_file, &operation.parameters)?; + let parameters = &operation.parameters; let param_names: HashSet<_> = parameters.iter().map(|p| p.name.as_str()).collect(); let has_param_api_version = param_names.contains("api-version"); let mut skip = HashSet::new(); if cg.spec.api_version().is_some() { skip.insert("api-version"); } - let parameters: Vec<_> = parameters.into_iter().filter(|p| !skip.contains(p.name.as_str())).collect(); + let parameters: Vec<_> = parameters.iter().filter(|p| !skip.contains(p.name.as_str())).collect(); - let fparams = create_function_params(cg, &operation.doc_file, ¶meters)?; + let fparams = create_function_params(¶meters)?; // see if there is a body parameter // let fresponse = create_function_return(operation_verb)?; @@ -550,7 +550,7 @@ fn format_path(path: &str) -> String { PARAM_RE.replace_all(path, "{}").to_string() } -fn create_function_params(_cg: &CodeGen, _doc_file: &Path, parameters: &[Parameter]) -> Result { +fn create_function_params(parameters: &[&Parameter]) -> Result { let mut params: Vec = Vec::new(); for param in parameters { let name = get_param_name(param)?; diff --git a/services/autorust/codegen/src/spec.rs b/services/autorust/codegen/src/spec.rs index 906b1d64fc..879b5ecf31 100644 --- a/services/autorust/codegen/src/spec.rs +++ b/services/autorust/codegen/src/spec.rs @@ -152,7 +152,7 @@ impl Spec { } /// Find the parameter for a given doc path and reference - pub fn resolve_parameter_ref>(&self, doc_file: P, reference: Reference) -> Result { + fn resolve_parameter_ref>(&self, doc_file: P, reference: Reference) -> Result { let doc_file = doc_file.as_ref(); let full_path = match reference.file { None => doc_file.to_owned(), @@ -167,7 +167,7 @@ impl Spec { } /// Resolve a reference or schema to a resolved schema - pub fn resolve_schema>(&self, doc_file: P, ref_or_schema: &ReferenceOr) -> Result { + fn resolve_schema>(&self, doc_file: P, ref_or_schema: &ReferenceOr) -> Result { match ref_or_schema { ReferenceOr::Item(schema) => Ok(ResolvedSchema { ref_key: None, @@ -177,15 +177,6 @@ impl Spec { } } - /// Resolve a collection of references or schemas to a collection of resolved schemas - pub fn resolve_schemas>(&self, doc_file: P, ref_or_schemas: &[ReferenceOr]) -> Result> { - let mut resolved = Vec::new(); - for schema in ref_or_schemas { - resolved.push(self.resolve_schema(&doc_file, schema)?); - } - Ok(resolved) - } - /// Resolve a collection of references or schemas to a collection of resolved schemas pub fn resolve_schema_map>( &self, @@ -218,14 +209,14 @@ impl Spec { Ok(resolved) } - pub fn resolve_parameter(&self, doc_file: &Path, parameter: &ReferenceOr) -> Result { + fn resolve_parameter(&self, doc_file: &Path, parameter: &ReferenceOr) -> Result { match parameter { ReferenceOr::Item(param) => Ok(param.clone()), ReferenceOr::Reference { reference, .. } => self.resolve_parameter_ref(doc_file, reference.clone()), } } - pub fn resolve_parameters(&self, doc_file: &Path, parameters: &[ReferenceOr]) -> Result> { + fn resolve_parameters(&self, doc_file: &Path, parameters: &[ReferenceOr]) -> Result> { let mut resolved = Vec::new(); for param in parameters { resolved.push(self.resolve_parameter(doc_file, param)?); @@ -234,18 +225,37 @@ impl Spec { } // only operations from listed input files - pub fn operations(&self) -> Result> { - let mut operations: Vec = Vec::new(); + fn operations_unresolved(&self) -> Result> { + let mut operations: Vec = Vec::new(); for (doc_file, doc) in self.docs() { if self.is_input_file(&doc_file) { let paths = self.resolve_path_map(doc_file, doc.paths())?; for (path, item) in &paths { - operations.extend(path_operations(doc_file, path, item)) + operations.extend(path_operations_unresolved(doc_file, path, item)) } } } Ok(operations) } + + // only operations from listed input files + pub fn operations(&self) -> Result> { + self.operations_unresolved()? + .into_iter() + .map({ + |op| { + Ok(WebOperation { + id: op.id, + path: op.path, + verb: op.verb, + parameters: self.resolve_parameters(&op.doc_file, &op.parameters)?, + responses: op.responses, + examples: op.examples, + }) + } + }) + .collect::, _>>() + } } type Result = std::result::Result; @@ -330,7 +340,7 @@ pub mod openapi { match item { ReferenceOr::Reference { reference, .. } => list.push(TypedReference::PathItem(reference.clone())), ReferenceOr::Item(item) => { - for operation in path_operations(&doc_file, path, item) { + for operation in path_operations_unresolved(&doc_file, path, item) { // parameters for param in &operation.parameters { match param { @@ -386,7 +396,8 @@ pub mod openapi { } } -pub struct WebOperation { +// contains unresolved parameters +pub struct WebOperationUnresolved { pub doc_file: PathBuf, pub id: Option, pub path: String, @@ -396,6 +407,16 @@ pub struct WebOperation { pub examples: MsExamples, } +// contains resolved parameters +pub struct WebOperation { + pub id: Option, + pub path: String, + pub verb: WebVerb, + pub parameters: Vec, + pub responses: IndexMap, + pub examples: MsExamples, +} + impl WebOperation { pub fn rust_module_name(&self) -> Option { match &self.id { @@ -462,7 +483,7 @@ struct OperationVerb<'a> { pub verb: WebVerb, } -pub fn path_operations>(doc_file: P, path: &str, item: &PathItem) -> Vec { +pub fn path_operations_unresolved>(doc_file: P, path: &str, item: &PathItem) -> Vec { vec![ OperationVerb { operation: item.get.as_ref(), @@ -498,7 +519,7 @@ pub fn path_operations>(doc_file: P, path: &str, item: &PathItem) Some(op) => { let mut parameters = item.parameters.clone(); parameters.append(&mut op.parameters.clone()); - Some(WebOperation { + Some(WebOperationUnresolved { doc_file: doc_file.as_ref().to_path_buf(), id: op.operation_id.clone(), path: path.to_string(), @@ -588,7 +609,6 @@ mod tests { #[test] fn test_function_name_from_operation_id() { let operation = WebOperation { - doc_file: PathBuf::from(""), id: Some("PrivateClouds_CreateOrUpdate".to_owned()), path: "/horse".to_owned(), verb: WebVerb::Get, @@ -603,7 +623,6 @@ mod tests { #[test] fn test_function_name_from_verb_and_path() { let operation = WebOperation { - doc_file: PathBuf::from(""), id: None, path: "/horse".to_owned(), verb: WebVerb::Get, @@ -618,7 +637,6 @@ mod tests { #[test] fn test_function_name_with_no_module_name() { let operation = WebOperation { - doc_file: PathBuf::from(""), id: Some("PerformConnectivityCheck".to_owned()), path: "/horse".to_owned(), verb: WebVerb::Put, From 9ee012d8906481808c85f1e513ba2a0e9bd88087 Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Thu, 18 Nov 2021 08:01:46 -0600 Subject: [PATCH 2/4] resolve_parameter_ref used by tests --- services/autorust/codegen/src/spec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/autorust/codegen/src/spec.rs b/services/autorust/codegen/src/spec.rs index 879b5ecf31..80f29067bb 100644 --- a/services/autorust/codegen/src/spec.rs +++ b/services/autorust/codegen/src/spec.rs @@ -152,7 +152,7 @@ impl Spec { } /// Find the parameter for a given doc path and reference - fn resolve_parameter_ref>(&self, doc_file: P, reference: Reference) -> Result { + pub fn resolve_parameter_ref>(&self, doc_file: P, reference: Reference) -> Result { let doc_file = doc_file.as_ref(); let full_path = match reference.file { None => doc_file.to_owned(), From 7f1ef810cff950f0adbf30ced060d83e2daa19bb Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Thu, 18 Nov 2021 08:08:41 -0600 Subject: [PATCH 3/4] make unresolved private --- services/autorust/codegen/src/spec.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/autorust/codegen/src/spec.rs b/services/autorust/codegen/src/spec.rs index 80f29067bb..8b7d3c04b2 100644 --- a/services/autorust/codegen/src/spec.rs +++ b/services/autorust/codegen/src/spec.rs @@ -397,7 +397,7 @@ pub mod openapi { } // contains unresolved parameters -pub struct WebOperationUnresolved { +struct WebOperationUnresolved { pub doc_file: PathBuf, pub id: Option, pub path: String, @@ -483,7 +483,7 @@ struct OperationVerb<'a> { pub verb: WebVerb, } -pub fn path_operations_unresolved>(doc_file: P, path: &str, item: &PathItem) -> Vec { +fn path_operations_unresolved>(doc_file: P, path: &str, item: &PathItem) -> Vec { vec![ OperationVerb { operation: item.get.as_ref(), From 274d8db8b4d139f6c585083adad387b4b0b6a711 Mon Sep 17 00:00:00 2001 From: Cameron Taggart Date: Thu, 18 Nov 2021 08:11:48 -0600 Subject: [PATCH 4/4] type annotation not needed --- services/autorust/codegen/src/spec.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/autorust/codegen/src/spec.rs b/services/autorust/codegen/src/spec.rs index 8b7d3c04b2..5fca11078e 100644 --- a/services/autorust/codegen/src/spec.rs +++ b/services/autorust/codegen/src/spec.rs @@ -254,7 +254,7 @@ impl Spec { }) } }) - .collect::, _>>() + .collect() } }