Skip to content

Commit 46881d6

Browse files
authored
add ContinuableCode for models (#1411)
1 parent 43826bc commit 46881d6

File tree

1 file changed

+71
-32
lines changed

1 file changed

+71
-32
lines changed

services/autorust/codegen/src/codegen_models.rs

+71-32
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ pub struct StructCode {
684684
struct_name_code: Ident,
685685
default_code: TokenStream,
686686
props: Vec<StructPropCode>,
687-
continuable: TokenStream,
687+
continuable: Option<ContinuableCode>,
688688
implement_default: bool,
689689
new_fn_params: Vec<TokenStream>,
690690
new_fn_body: TokenStream,
@@ -912,17 +912,69 @@ fn create_struct(
912912

913913
let doc_comment = DocCommentCode::from(&schema.schema.common.description);
914914

915-
let mut continuable = quote! {};
916-
if let Some(pageable) = pageable {
917-
if let Some(name) = &pageable.next_link_name {
918-
let field_name = name.to_snake_case_ident()?;
915+
let continuable = ContinuableCode::from_pageable(struct_name_code.clone(), pageable, field_names)?;
916+
917+
Ok(StructCode {
918+
doc_comment,
919+
struct_name_code,
920+
default_code,
921+
props,
922+
continuable,
923+
implement_default: schema.implement_default(),
924+
new_fn_params,
925+
new_fn_body,
926+
mod_code,
927+
ns,
928+
})
929+
}
930+
931+
pub struct ContinuableCode {
932+
pub struct_name: Ident,
933+
pub field_name: Option<Ident>,
934+
pub is_required: Option<bool>,
935+
}
936+
937+
impl ContinuableCode {
938+
pub fn new(struct_name: Ident, field_name: Option<Ident>, is_required: Option<bool>) -> Self {
939+
Self {
940+
struct_name,
941+
field_name,
942+
is_required,
943+
}
944+
}
945+
946+
pub fn from_pageable(struct_name: Ident, pageable: Option<&MsPageable>, field_names: HashMap<String, bool>) -> Result<Option<Self>> {
947+
if let Some(pageable) = pageable {
948+
let field_name = if let Some(name) = &pageable.next_link_name {
949+
let field_name = name.to_snake_case_ident()?;
950+
Some(field_name)
951+
} else {
952+
None
953+
};
954+
let is_required = field_name.as_ref().and_then(|field_name| field_names.get(&format!("{field_name}")));
955+
Ok(Some(Self::new(struct_name, field_name, is_required.cloned())))
956+
} else {
957+
Ok(None)
958+
}
959+
}
960+
}
961+
962+
impl ToTokens for ContinuableCode {
963+
fn to_tokens(&self, tokens: &mut TokenStream) {
964+
let Self {
965+
struct_name,
966+
field_name,
967+
is_required,
968+
} = self;
969+
970+
if let Some(field_name) = field_name {
919971
// when there are multiple responses, we only add the Continuable
920972
// for the cases that have the field we care about.
921-
// println!("checking {} {} {}", struct_name_code, field_name, field_names.contains(&format!("{}", field_name)));
922-
if let Some(is_required) = field_names.get(&format!("{field_name}")) {
973+
// println!("checking {} {} {}", struct_name_code, field_name, is_required);
974+
if let Some(is_required) = is_required {
923975
if *is_required {
924-
continuable = quote! {
925-
impl azure_core::Continuable for #struct_name_code {
976+
tokens.extend(quote! {
977+
impl azure_core::Continuable for #struct_name {
926978
type Continuation = String;
927979
fn continuation(&self) -> Option<Self::Continuation> {
928980
if self.#field_name.is_empty() {
@@ -932,60 +984,47 @@ fn create_struct(
932984
}
933985
}
934986
}
935-
};
987+
});
936988
} else {
937-
continuable = quote! {
938-
impl azure_core::Continuable for #struct_name_code {
989+
tokens.extend(quote! {
990+
impl azure_core::Continuable for #struct_name {
939991
type Continuation = String;
940992
fn continuation(&self) -> Option<Self::Continuation> {
941993
self.#field_name.clone().filter(|value| !value.is_empty())
942994
}
943995
}
944-
};
996+
});
945997
}
946998
} else {
947999
// In a number of cases, such as USqlAssemblyList used in
9481000
// datalake-analytics, the next link name is provided, but the
9491001
// field doesn't exist in the response schema. Handle that by
9501002
// adding a Continuable that always returns None.
951-
continuable = quote! {
952-
impl azure_core::Continuable for #struct_name_code {
1003+
tokens.extend(quote! {
1004+
impl azure_core::Continuable for #struct_name {
9531005
type Continuation = String;
9541006
fn continuation(&self) -> Option<Self::Continuation> {
9551007
None
9561008
}
9571009
}
958-
};
1010+
});
9591011
}
9601012
} else {
9611013
// In a number of cases, such as DimensionsListResult used in
9621014
// costmanagement, the next link name is null, and it's not provided
9631015
// via a header or sometimes used in other responses.
9641016
//
9651017
// Handle that by // adding a Continuable that always returns None.
966-
continuable = quote! {
967-
impl azure_core::Continuable for #struct_name_code {
1018+
tokens.extend(quote! {
1019+
impl azure_core::Continuable for #struct_name {
9681020
type Continuation = String;
9691021
fn continuation(&self) -> Option<Self::Continuation> {
9701022
None
9711023
}
9721024
}
973-
};
1025+
});
9741026
}
9751027
}
976-
977-
Ok(StructCode {
978-
doc_comment,
979-
struct_name_code,
980-
default_code,
981-
props,
982-
continuable,
983-
implement_default: schema.implement_default(),
984-
new_fn_params,
985-
new_fn_body,
986-
mod_code,
987-
ns,
988-
})
9891028
}
9901029

9911030
pub struct StructPropCode {

0 commit comments

Comments
 (0)