use proc_macro2::TokenStream;
use super::{BindingBackend, ShapeParts};
use crate::analysis::EmitShape;
use crate::codegen::{BindingMode, MethodHandler, ServiceHandler};
fn shape_parts<'a>(
backend: &dyn BindingBackend,
method: &'a MethodHandler<'a>,
mode: BindingMode,
) -> ShapeParts<'a> {
ShapeParts {
param_defs: backend.param_defs(method, mode),
client_call: backend.client_call(method, mode),
method,
mode,
}
}
fn emit_for_shape(
backend: &dyn BindingBackend,
method: &MethodHandler<'_>,
mode: BindingMode,
) -> TokenStream {
let parts = shape_parts(backend, method, mode);
match method.emit_shape() {
EmitShape::List => backend.emit_list(&parts),
EmitShape::Create => backend.emit_create(&parts),
EmitShape::GetUpdate => backend.emit_get_update(&parts),
EmitShape::Delete => backend.emit_delete(&parts),
}
}
fn scoped_instance_method(
backend: &dyn BindingBackend,
method: MethodHandler<'_>,
) -> Option<TokenStream> {
method
.is_scoped_instance_method()
.then(|| emit_for_shape(backend, &method, BindingMode::Scoped))
}
fn root_method(
backend: &dyn BindingBackend,
method: MethodHandler<'_>,
mode: BindingMode,
) -> Option<TokenStream> {
match mode {
BindingMode::Scoped => {
let collection_shaped =
matches!(method.emit_shape(), EmitShape::List | EmitShape::Create);
(method.is_collection_method() && collection_shaped)
.then(|| emit_for_shape(backend, &method, mode))
}
BindingMode::Flat => Some(emit_for_shape(backend, &method, mode)),
}
}
pub(crate) fn scoped_client_methods(
backend: &dyn BindingBackend,
service: &ServiceHandler<'_>,
) -> Vec<TokenStream> {
service
.methods()
.filter_map(|m| scoped_instance_method(backend, m))
.collect()
}
pub(crate) fn root_client_methods(
backend: &dyn BindingBackend,
services: &[&ServiceHandler<'_>],
) -> Vec<TokenStream> {
services
.iter()
.flat_map(|s| {
let mode = s.binding_mode();
s.methods()
.filter_map(move |m| root_method(backend, m, mode))
.collect::<Vec<_>>()
})
.collect()
}
pub(crate) fn resource_accessor_methods(
backend: &dyn BindingBackend,
services: &[&ServiceHandler<'_>],
) -> Vec<TokenStream> {
services
.iter()
.filter_map(|s| backend.emit_resource_accessor(s))
.collect()
}