ruma_macros/api/request/
outgoing.rs1use proc_macro2::TokenStream;
2use quote::quote;
3
4use super::{KIND, Request, RequestQuery};
5use crate::{
6 api::StructSuffix,
7 util::{RumaCommon, RumaCommonReexport, StructFieldExt},
8};
9
10impl Request {
11 pub fn expand_outgoing(&self, ruma_common: &RumaCommon) -> TokenStream {
13 let bytes = ruma_common.reexported(RumaCommonReexport::Bytes);
14 let http = ruma_common.reexported(RumaCommonReexport::Http);
15
16 let path_fields = self.path.expand_fields();
17 let path_idents = self.path.0.iter().map(|field| field.ident());
18
19 let query_serialize = self.query.expand_serialize(ruma_common);
20 let query_fields = self.query.expand_fields();
21
22 let headers_serialize = self.headers.expand_serialize(KIND, &self.body, ruma_common, &http);
23 let headers_fields = self.headers.expand_fields();
24
25 let body_serialize = self.body.expand_serialize(KIND, ruma_common);
26 let body_fields = self.body.expand_fields();
27
28 let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl();
29 let ident = &self.ident;
30 let error_ty = &self.error_ty;
31 let request = KIND.as_variable_ident();
32
33 quote! {
34 #[automatically_derived]
35 #[cfg(feature = "client")]
36 impl #impl_generics #ruma_common::api::OutgoingRequest for #ident #ty_generics #where_clause {
37 type EndpointError = #error_ty;
38 type IncomingResponse = Response;
39
40 fn try_into_http_request<T: ::std::default::Default + #bytes::BufMut + ::std::convert::AsRef<[::std::primitive::u8]>>(
41 self,
42 base_url: &::std::primitive::str,
43 authentication_input: <<Self as #ruma_common::api::Metadata>::Authentication as #ruma_common::api::auth_scheme::AuthScheme>::Input<'_>,
44 path_builder_input: <<Self as #ruma_common::api::Metadata>::PathBuilder as #ruma_common::api::path_builder::PathBuilder>::Input<'_>,
45 ) -> ::std::result::Result<#http::Request<T>, #ruma_common::api::error::IntoHttpError> {
46 let Self {
47 #path_fields
48 #query_fields
49 #headers_fields
50 #body_fields
51 } = self;
52
53 let request_query_string = #query_serialize;
54
55 let mut #request = #http::Request::builder()
56 .method(<Self as #ruma_common::api::Metadata>::METHOD)
57 .uri(<Self as #ruma_common::api::Metadata>::make_endpoint_url(
58 path_builder_input,
59 base_url,
60 &[ #( &#path_idents ),* ],
61 &request_query_string,
62 )?)
63 .body(#body_serialize)?;
64
65 #headers_serialize
66
67 <<Self as #ruma_common::api::Metadata>::Authentication as #ruma_common::api::auth_scheme::AuthScheme>::add_authentication(
68 &mut #request,
69 authentication_input
70 )
71 .map_err(|error| #ruma_common::api::error::IntoHttpError::Authentication(error.into()))?;
72
73 Ok(#request)
74 }
75 }
76 }
77 }
78}
79
80impl RequestQuery {
81 fn expand_serialize(&self, ruma_common: &RumaCommon) -> TokenStream {
83 if matches!(self, Self::None) {
84 return quote! { "" };
85 }
86
87 let serde_html_form = ruma_common.reexported(RumaCommonReexport::SerdeHtmlForm);
88 let fields = self.expand_fields();
89 let serde_struct = KIND.as_struct_ident(StructSuffix::Query);
90
91 quote! {{
92 let request_query = #serde_struct {
93 #fields
94 };
95
96 &#serde_html_form::to_string(request_query)?
97 }}
98 }
99}