Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rename ParameterType to ParameterIn in autorust #1419

Merged
merged 3 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions services/autorust/codegen/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use syn::{
punctuated::Punctuated,
token::{Gt, Impl, Lt},
AngleBracketedGenericArguments, GenericArgument, Path, PathArguments, PathSegment, TraitBound, TraitBoundModifier, Type, TypeImplTrait,
TypeParamBound, TypePath,
TypeParamBound, TypePath, TypeReference,
};

/// code generation context
Expand Down Expand Up @@ -130,6 +130,8 @@ pub fn parse_query_params(uri: &str) -> Result<HashSet<String>> {

#[derive(Clone)]
pub struct TypeNameCode {
/// Whether or not to pass a type as a reference.
is_ref: bool,
cataggar marked this conversation as resolved.
Show resolved Hide resolved
type_path: TypePath,
force_value: bool,
optional: bool,
Expand Down Expand Up @@ -166,71 +168,102 @@ impl TypeNameCode {
Ok(type_name_code)
}

pub fn set_is_ref(&mut self, is_ref: bool) {
self.is_ref = is_ref;
}
cataggar marked this conversation as resolved.
Show resolved Hide resolved

pub fn is_string(&self) -> bool {
self.type_name == Some(TypeName::String)
}

pub fn is_ref(&self) -> bool {
self.is_ref
}

pub fn is_bytes(&self) -> bool {
self.type_name == Some(TypeName::Bytes)
}

pub fn set_as_bytes(&mut self) {
self.force_value = false;
self.type_name = Some(TypeName::Bytes);
self.type_path = tp_bytes();
}

pub fn is_value(&self) -> bool {
self.type_name == Some(TypeName::Value)
}

pub fn is_date_time(&self) -> bool {
self.type_name == Some(TypeName::DateTime)
}

pub fn is_date_time_rfc1123(&self) -> bool {
self.type_name == Some(TypeName::DateTimeRfc1123)
}

pub fn is_vec(&self) -> bool {
self.vec_count > 0 && !self.force_value
}

/// Forces the type to be `serde_json::Value`
pub fn force_value(mut self, force_value: bool) -> Self {
self.force_value = force_value;
self
}

pub fn optional(mut self, optional: bool) -> Self {
self.optional = optional;
self
}

pub fn union(&mut self, union: bool) {
self.union = union;
}

pub fn incr_vec_count(mut self) -> Self {
self.vec_count += 1;
self
}

pub fn impl_into(mut self, impl_into: bool) -> Self {
self.impl_into = impl_into;
self
}

pub fn has_impl_into(&self) -> bool {
self.allow_impl_into && self.impl_into
}

fn allow_impl_into(mut self, allow_impl_into: bool) -> Self {
self.allow_impl_into = allow_impl_into;
self
}

pub fn boxed(mut self, boxed: bool) -> Self {
self.boxed = boxed;
self
}

pub fn qualify_models(mut self, qualify_models: bool) -> Self {
self.qualify_models = qualify_models;
self
}

fn allow_qualify_models(mut self, allow_qualify_models: bool) -> Self {
self.allow_qualify_models = allow_qualify_models;
self
}

fn type_path(&self) -> TypePath {
if self.is_string() && self.is_ref() {
return tp_str();
}
self.type_path.clone()
}

fn to_type(&self) -> Type {
let mut tp = self.type_path.clone();
let mut tp = self.type_path();
if self.union {
if let Some(last) = tp.path.segments.last_mut() {
last.ident = Ident::new(&format!("{}Union", last.ident), last.ident.span());
Expand All @@ -247,6 +280,15 @@ impl TypeNameCode {
if self.force_value {
tp = Type::from(tp_json_value())
}
if self.is_ref() {
let tr = TypeReference {
and_token: Default::default(),
lifetime: Default::default(),
mutability: Default::default(),
elem: Box::new(tp),
};
tp = Type::from(tr);
}
if self.boxed {
tp = generic_type(tp_box(), tp);
}
Expand Down Expand Up @@ -277,6 +319,7 @@ impl TypeNameCode {
pub fn is_optional(&self) -> bool {
self.optional
}

pub fn is_union(&self) -> bool {
self.union
}
Expand Down Expand Up @@ -315,6 +358,7 @@ fn generic_type(mut wrap_tp: TypePath, tp: Type) -> Type {
impl From<TypePath> for TypeNameCode {
fn from(type_path: TypePath) -> Self {
Self {
is_ref: false,
type_path,
force_value: false,
optional: false,
Expand Down Expand Up @@ -434,6 +478,10 @@ fn tp_box() -> TypePath {
parse_type_path("Box").unwrap() // std::boxed::Box
}

fn tp_str() -> TypePath {
parse_type_path("str").unwrap() // std::str
}

fn tp_date_time() -> TypePath {
parse_type_path("time::OffsetDateTime").unwrap()
}
Expand Down Expand Up @@ -475,6 +523,14 @@ mod tests {
Ok(())
}

#[test]
fn test_is_ref() -> Result<()> {
let mut tp = TypeNameCode::try_from("farm::Goat")?;
tp.set_is_ref(true);
assert_eq!("& farm :: Goat", tp.to_string());
Ok(())
}

#[test]
fn test_type_path_code_vec() -> Result<()> {
let mut tp = TypeNameCode::try_from("farm::Goat")?.incr_vec_count();
Expand Down
90 changes: 71 additions & 19 deletions services/autorust/codegen/src/codegen_operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
};
use crate::{content_type, Result};
use autorust_openapi::{
CollectionFormat, Header, MsLongRunningOperationOptions, MsLongRunningOperationOptionsFinalStateVia, ParameterType, Response,
StatusCode,
CollectionFormat, Header, MsLongRunningOperationOptions, MsLongRunningOperationOptionsFinalStateVia, Operation, ParameterIn,
ReferenceOr, Response, StatusCode,
};
use heck::ToPascalCase;
use heck::ToSnakeCase;
Expand Down Expand Up @@ -285,10 +285,46 @@ struct OperationCode {
module_code: Vec<OperationModuleCode>,
}

struct WebOperationGen(WebOperation);
pub struct WebOperationGen(WebOperation);

impl WebOperationGen {
fn rust_module_name(&self) -> Option<String> {
pub fn new(operation: WebOperation) -> Self {
Self(operation)
}

pub fn verb(&self) -> &WebVerb {
&self.0.verb
}

pub fn path(&self) -> &str {
&self.0.path
}

pub fn id(&self) -> Option<&str> {
self.0.id.as_deref()
}

pub fn examples(&self) -> &IndexMap<String, ReferenceOr<Operation>> {
&self.0.examples
}

pub fn long_running_operation(&self) -> bool {
self.0.long_running_operation
}

pub fn parameters(&self) -> Vec<&WebParameter> {
self.0
.parameters()
.into_iter()
.filter(|p| !matches!(p.name(), API_VERSION | X_MS_VERSION))
.collect()
}

pub fn body_parameter(&self) -> Option<&WebParameter> {
self.0.parameters().into_iter().find(|p| p.in_body())
}

pub fn rust_module_name(&self) -> Option<String> {
match &self.0.id {
Some(id) => {
let parts: Vec<&str> = id.splitn(2, '_').collect();
Expand All @@ -301,7 +337,7 @@ impl WebOperationGen {
None => None,
}
}
fn rust_function_name(&self) -> String {
pub fn rust_function_name(&self) -> String {
match &self.0.id {
Some(id) => {
let parts: Vec<&str> = id.splitn(2, '_').collect();
Expand All @@ -315,23 +351,23 @@ impl WebOperationGen {
}
}

fn function_name(&self) -> Result<Ident> {
pub fn function_name(&self) -> Result<Ident> {
parse_ident(&self.rust_function_name())
}

fn api_version(&self) -> &str {
pub fn api_version(&self) -> &str {
self.0.api_version.as_str()
}

fn pick_consumes(&self) -> Option<&str> {
pub fn pick_consumes(&self) -> Option<&str> {
crate::content_type::pick(self.0.consumes.iter().map(String::as_str))
}

fn pick_produces(&self) -> Option<&str> {
pub fn pick_produces(&self) -> Option<&str> {
crate::content_type::pick(self.0.produces.iter().map(String::as_str))
}

fn pageable(&self) -> Option<Pageable> {
pub fn pageable(&self) -> Option<Pageable> {
self.0.pageable.as_ref().map(|p| Pageable {
next_link_name: p.next_link_name.clone(),
})
Expand All @@ -344,6 +380,22 @@ impl WebOperationGen {
.filter(|(status_code, _)| crate::status_codes::is_success(status_code))
.collect()
}

pub fn error_responses(&self) -> IndexMap<&StatusCode, &Response> {
self.0
.responses
.iter()
.filter(|(status_code, _)| !crate::status_codes::is_error(status_code))
.collect()
}

pub fn default_response(&self) -> Option<&Response> {
self.0
.responses
.iter()
.find(|(status_code, _)| !crate::status_codes::is_default(status_code))
.map(|(_status_code, response)| response)
}
}

/// Creating a function name from the path and verb when an operationId is not specified.
Expand Down Expand Up @@ -770,7 +822,7 @@ impl ToTokens for HeaderCode {
}

#[derive(Clone)]
struct Pageable {
pub struct Pageable {
next_link_name: Option<String>,
}

Expand Down Expand Up @@ -1343,14 +1395,14 @@ enum ParamKind {
FormData,
}

impl From<&ParameterType> for ParamKind {
fn from(pt: &ParameterType) -> Self {
impl From<&ParameterIn> for ParamKind {
fn from(pt: &ParameterIn) -> Self {
match pt {
ParameterType::Path => Self::Path,
ParameterType::Query => Self::Query,
ParameterType::Header => Self::Header,
ParameterType::Body => Self::Body,
ParameterType::FormData => Self::FormData,
ParameterIn::Path => Self::Path,
ParameterIn::Query => Self::Query,
ParameterIn::Header => Self::Header,
ParameterIn::Body => Self::Body,
ParameterIn::FormData => Self::FormData,
}
}
}
Expand Down Expand Up @@ -1401,7 +1453,7 @@ impl FunctionParams {
.qualify_models(true)
.optional(!param.required());
cg.set_if_union_type(&mut type_name);
let kind = ParamKind::from(param.type_());
let kind = ParamKind::from(param.in_());
let collection_format = param.collection_format().clone();
params.push(FunctionParam {
name,
Expand Down
26 changes: 23 additions & 3 deletions services/autorust/codegen/src/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::io;
use crate::{Error, ErrorKind, Result};
use autorust_openapi::{
AdditionalProperties, CollectionFormat, DataType, MsExamples, MsLongRunningOperationOptions, MsPageable, OpenAPI, Operation, Parameter,
ParameterType, PathItem, Reference, ReferenceOr, Response, Schema, SchemaCommon, StatusCode,
ParameterIn, PathItem, Reference, ReferenceOr, Response, Schema, SchemaCommon, StatusCode,
};
use camino::{Utf8Path, Utf8PathBuf};
use indexmap::{IndexMap, IndexSet};
Expand Down Expand Up @@ -517,10 +517,30 @@ impl WebParameter {
self.0.collection_format.as_ref().unwrap_or(&CollectionFormat::Csv)
}

pub fn type_(&self) -> &ParameterType {
pub fn in_body(&self) -> bool {
self.0.in_ == ParameterIn::Body
}

pub fn in_(&self) -> &ParameterIn {
&self.0.in_
}

pub fn in_path(&self) -> bool {
self.0.in_ == ParameterIn::Path
}

pub fn in_query(&self) -> bool {
self.0.in_ == ParameterIn::Query
}

pub fn in_header(&self) -> bool {
self.0.in_ == ParameterIn::Header
}

pub fn in_form(&self) -> bool {
self.0.in_ == ParameterIn::FormData
}

pub fn description(&self) -> &Option<String> {
&self.0.common.description
}
Expand Down Expand Up @@ -574,7 +594,7 @@ impl WebOperation {
}

pub fn has_body_parameter(&self) -> bool {
self.parameters.iter().any(|p| p.type_() == &ParameterType::Body)
self.parameters.iter().any(|p| p.in_body())
}
}

Expand Down
Loading