{{! Copyright (c) Meta Platforms, Inc. and affiliates. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. }} {{#service:interactions?}} pub mod {{service:snake}} {{>lib/block}} use super::*; {{#service:interactions}} {{>lib/client}} {{/service:interactions}} } {{/service:interactions?}} {{^service:interaction?}} {{>lib/client_trait}} {{/service:interaction?}} /// Client definitions for `{{service:rust_name}}`. pub struct {{service:rust_name}}Impl
{ {{#service:extends}} parent: {{service:client_package}}::{{service:rust_name}}Impl
,
{{/service:extends}}
{{^service:extends}}
transport: T,
_phantom: ::std::marker::PhantomData {{service:rust_name}}Impl
where
P: ::fbthrift::Protocol,
T: ::fbthrift::Transport,
{{! require P::Frame and T to have compatible DecBuf and EncBuf::Final }}
P::Frame: ::fbthrift::Framing : ::fbthrift::BufMutExt ::new(transport);
Self { parent }
{{/service:extends}}
{{^service:extends}}
Self {
transport,
_phantom: ::std::marker::PhantomData,
}
{{/service:extends}}
}
pub fn transport(&self) -> &T {
::fbthrift::help::GetTransport::transport(self)
}
{{#service:rustFunctions}}
{{^function:starts_interaction?}}{{^function:sink?}}
fn _{{function:name}}_impl(
&self,{{!
}}{{#function:args}}
arg_{{field:name}}: {{>lib/arg}},{{!
}}{{/function:args}}
rpc_options: T::RpcOptions,
) -> {{>lib/client_return_type}} {
use ::tracing::Instrument as _;
use ::futures::FutureExt as _;
{{#function:stream?}}
use ::futures::StreamExt as _;
use ::fbthrift::Deserialize as _;
{{/function:stream?}}
const SERVICE_NAME: &::std::ffi::CStr = c"{{service:parent_service_name}}";
const SERVICE_METHOD_NAME: &::std::ffi::CStr = c"{{service:parent_service_name}}.{{#service:interaction?}}{{service:name}}.{{/service:interaction?}}{{function:name}}";
{{#function:creates_interaction?}}
const INTERACTION_NAME: &::std::ffi::CStr = c"{{function:interaction_name}}";
{{/function:creates_interaction?}}
let args = self::Args_{{service:rust_name}}_{{function:name}} {
{{#function:args}}
{{field:rust_name}}: arg_{{field:name}},
{{/function:args}}
_phantom: ::std::marker::PhantomData,
};
{{#function:creates_interaction?}}
let interaction_transport = match self.transport().create_interaction(INTERACTION_NAME) {
::std::result::Result::Ok(res) => res,
::std::result::Result::Err(err) => return ::futures::future::err(err.into()).boxed(),
};
let interaction_impl = {{program:crate}}::{{service:snake}}::{{function:interaction_name}}Impl:: ::new(interaction_transport);
let transport = interaction_impl.transport();
{{/function:creates_interaction?}}{{^function:creates_interaction?}}
let transport = self.transport();
{{/function:creates_interaction?}}
// need to do call setup outside of async block because T: Transport isn't Send
let request_env = match ::fbthrift::help::serialize_request_envelope:: ("{{#service:interaction?}}{{service:name}}.{{/service:interaction?}}{{function:name}}", &args) {
::std::result::Result::Ok(res) => res,
::std::result::Result::Err(err) => return ::futures::future::err(err.into()).boxed(),
};
{{#function:stream?}}
let call_stream = transport
.call_stream(SERVICE_NAME, SERVICE_METHOD_NAME, request_env, rpc_options)
.instrument(::tracing::trace_span!("call_stream", method = "{{service:name}}.{{function:name}}"));
{{/function:stream?}}{{^function:stream?}}
let call = transport
.call(SERVICE_NAME, SERVICE_METHOD_NAME, request_env, rpc_options)
.instrument(::tracing::trace_span!("call", method = "{{service:name}}.{{function:name}}"));
{{/function:stream?}}
async move {
{{#function:stream?}}{{!
******************************
******* STREAMING BODY *******
******************************
}}
let (initial, stream) = call_stream.await?;
let new_stream = stream.then(|item_res| {
async move {
match item_res {
::std::result::Result::Err(err) =>
::std::result::Result::Err({{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}StreamError::from(err)),
::std::result::Result::Ok(item_enc) => {
S::spawn(move || {
match item_enc {
::fbthrift::ClientStreamElement::Reply(payload) => {
let mut de = P::deserializer(payload);
<{{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}StreamReader as ::fbthrift::help::DeserializeExn>::read_result(&mut de)
}
::fbthrift::ClientStreamElement::ApplicationEx(payload) => {
let mut de = P::deserializer(payload);
let aexn = ::fbthrift::ApplicationException::read(&mut de)?;
::std::result::Result::Ok(::std::result::Result::Err({{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}StreamError::ApplicationException(aexn)))
}
}
}).await.map_err(::anyhow::Error::from)??
}
}
}
})
.boxed();
let de = P::deserializer(initial);
let res = ::fbthrift::help::async_deserialize_response_envelope:: (de)
.await??
.map({{!
}}{{#function:stream_has_first_response?}}move |initial| (initial, new_stream){{/function:stream_has_first_response?}}{{!
}}{{^function:stream_has_first_response?}}move |_| new_stream{{/function:stream_has_first_response?}}{{!
}});
{{/function:stream?}}{{^function:stream?}}{{!
******************************
**** SINGLE RESPONSE BODY ****
******************************
}}
let reply_env = call.await?;
let de = P::deserializer(reply_env);
let res = ::fbthrift::help::async_deserialize_response_envelope:: (de).await?;
let res = match res {
::std::result::Result::Ok(res) => res,
::std::result::Result::Err(aexn) => {
::std::result::Result::Err({{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}Error::ApplicationException(aexn))
}
};
{{/function:stream?}}
{{#function:return_type}}{{#function:creates_interaction?}}{{!
***********************************
**** Add interaction to result ****
***********************************
}}
let interaction_client: {{program:crate}}::client::{{service:snake}}::{{function:interaction_name}}Client = ::std::sync::Arc::new(interaction_impl);
{{#type:void?}}
res?;
::std::result::Result::Ok(interaction_client)
{{/type:void?}}{{^type:void?}}
::std::result::Result::Ok((interaction_client, res?))
{{/type:void?}}{{!
}}{{/function:creates_interaction?}}{{^function:creates_interaction?}}
res
{{/function:creates_interaction?}}{{/function:return_type}}
}
.instrument(::tracing::info_span!("stream", method = "{{service:name}}.{{function:name}}"))
.boxed()
}
{{/function:sink?}}{{/function:starts_interaction?}}
{{/service:rustFunctions}}
}
impl ::fbthrift::help::GetTransport
where
T: ::fbthrift::Transport,
{
fn transport(&self) -> &T {
{{#service:extends}}
self.parent.transport()
{{/service:extends}}
{{^service:extends}}
&self.transport
{{/service:extends}}
}
}
{{#service:extendedClients}}
#[allow(deprecated)]{{! `dependencies` modules are deprecated other than for packagePrefix to use }}
impl<'a, P, T, S> {{!
}}{{#extendedService:service}}{{!
}}::std::convert::AsRef
where
P: ::fbthrift::Protocol,
T: ::fbthrift::Transport,
{{! require P::Frame and T to have compatible DecBuf and EncBuf::Final }}
P::Frame: ::fbthrift::Framing : ::fbthrift::BufMutExt
where
P: ::fbthrift::Protocol,
T: ::fbthrift::Transport,
{{! require P::Frame and T to have compatible DecBuf and EncBuf::Final }}
P::Frame: ::fbthrift::Framing : ::fbthrift::BufMutExt for self::Args_{{service:rust_name}}_{{function:name}}<'a> {
#[inline]{{! No cost because there's only one caller; with luck will mitigate move cost of args. }}
#[::tracing::instrument(skip_all, level = "trace", name = "serialize_args", fields(method = "{{service:name}}.{{function:name}}"))]
fn write(&self, p: &mut P) {
p.write_struct_begin("args");{{!
}}{{#function:args}}
p.write_field_begin({{!
}}"{{field:name}}", {{!
}}{{#field:type}}{{>lib/ttype}}{{/field:type}}, {{!
}}{{field:key}}i16{{!
}});
{{#field:type}}{{!
}}{{#type:has_adapter?}}{{!
}}::fbthrift::Serialize::write(&{{>lib/adapter/qualified}}::to_thrift_field:: {{service:rust_name}} for {{service:rust_name}}Impl
where
P: ::fbthrift::Protocol,
T: ::fbthrift::Transport,
{{! require P::Frame and T to have compatible DecBuf and EncBuf::Final }}
P::Frame: ::fbthrift::Framing : ::fbthrift::BufMutExt ::new(
self.transport().create_interaction(c"{{function:interaction_name}}")?
)
)
)
}
{{/function:starts_interaction?}}{{/service:rustFunctions}}
}
impl {{service:rust_name}}Ext
where
P: ::fbthrift::Protocol,
T: ::fbthrift::Transport,
{{! require P::Frame and T to have compatible DecBuf and EncBuf::Final }}
P::Frame: ::fbthrift::Framing : ::fbthrift::BufMutExt (
protocol: P,
transport: T,
) -> ::std::sync::Arc (
protocol: P,
transport: T,
spawner: S,
) -> ::std::sync::Arc ::new(transport))
}
}
impl (
protocol: P,
transport: T,
) -> ::std::sync::Arc (
protocol: P,
transport: T,
spawner: S,
) -> ::std::sync::Arc ::new(transport))
}
}
pub type {{service:rust_name}}DynClient = (protocol: P, transport: T, spawner: S) -> ::std::sync::Arc