{{! Copyright (c) Meta Platforms, Inc. and its 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}}{{>lib/client}} {{/service:interactions}} /// 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 {
{{#service:extends}}
self.parent.transport()
{{/service:extends}}
{{^service:extends}}
&self.transport
{{/service:extends}}
}
{{#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 ::const_cstr::const_cstr;
use ::tracing::Instrument as _;
use ::futures::FutureExt as _;
{{#function:stream?}}
use ::futures::StreamExt as _;
use ::fbthrift::Deserialize as _;
{{/function:stream?}}
const_cstr! {
SERVICE_NAME = "{{service:parent_service_name}}";
SERVICE_METHOD_NAME = "{{service:parent_service_name}}.{{#service:interaction?}}{{service:name}}.{{/service:interaction?}}{{function:name}}";
{{#function:creates_interaction?}}
INTERACTION_NAME = "{{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.as_cstr()) {
::std::result::Result::Ok(res) => res,
::std::result::Result::Err(err) => return ::futures::future::err(err.into()).boxed(),
};
let interaction_impl = {{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.as_cstr(), SERVICE_METHOD_NAME.as_cstr(), 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.as_cstr(), SERVICE_METHOD_NAME.as_cstr(), 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) => {
let res = S::spawn(move || {
match item_enc {
::fbthrift::ClientStreamElement::Reply(payload) => {
let mut de = P::deserializer(payload);
{{program:crate}}::services::{{service:snake}}::{{function:upcamel}}StreamExn::read(&mut de)
}
::fbthrift::ClientStreamElement::ApplicationEx(payload) => {
let mut de = P::deserializer(payload);
::fbthrift::ApplicationException::read(&mut de).map({{program:crate}}::services::{{service:snake}}::{{function:upcamel}}StreamExn::ApplicationException)
}
}
}).await?;
let item: ::std::result::Result<{{!
}}{{>lib/function_stream_elem_type}}, {{!
}}{{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}StreamError> =
::std::convert::From::from(res);
item
}
}
}
})
.boxed();
let de = P::deserializer(initial);
let res: {{program:crate}}::services::{{service:snake}}::{{function:upcamel}}ResponseExn =
::fbthrift::help::async_deserialize_response_envelope:: (de).await?.0?;
{{#function:stream_has_first_response?}}
let initial: ::std::result::Result<{{>lib/function_stream_first_response_type}}, {{!
}}{{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}Error> =
::std::convert::From::from(res);
let res = initial.map(move |initial| (initial, new_stream));
{{/function:stream_has_first_response?}}
{{^function:stream_has_first_response?}}
let initial: ::std::result::Result<(), {{program:crate}}::errors::{{service:snake}}::{{function:upcamel}}Error> =
::std::convert::From::from(res);
let res = initial.map(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, _de): (::std::result::Result<{{program:crate}}::services::{{service:snake}}::{{function:upcamel}}Exn, _>, _) =
::fbthrift::help::async_deserialize_response_envelope:: (de).await?;
let res = match res {
::std::result::Result::Ok(exn) => ::std::convert::From::from(exn),
::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::{{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}}
}
{{#service:extendedServers}}
#[allow(deprecated)]{{! `dependencies` modules are deprecated other than for packagePrefix to use }}
impl {{!
}}{{#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 {{!
}}{{#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 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(INTERACTION_NAME.as_cstr())?
)
)
)
}
{{/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 {{service:rust_name}}Ext