fizyr-rpc-macros 0.5.1

procedural macros for the fizyr-rpc crate
Documentation
use proc_macro2::{TokenStream, Span};
use quote::quote;

use crate::interface::parse::cooked::InterfaceDefinition;

use super::is_unit_type;
use super::message_enum::generate_message_enum;

pub fn generate_streams(item_tokens: &mut TokenStream, client_impl_tokens: &mut TokenStream, fizyr_rpc: &syn::Ident, interface: &InterfaceDefinition) {
	if !interface.streams().is_empty() {
		generate_message_enum(
			item_tokens,
			fizyr_rpc,
			interface.streams(),
			&syn::Ident::new("StreamMessage", Span::call_site()),
			&format!("A stream message for the {} interface.", interface.name()),
		);
	}
	for stream in interface.streams() {
		let service_id = stream.service_id();
		let fn_name = syn::Ident::new(&format!("send_{}", stream.name()), Span::call_site());
		let fn_doc = format!("Send a `{}` stream message to the remote peer.", stream.name());
		let body_arg;
		let body_val;
		let body_type = stream.body_type();
		if is_unit_type(body_type) {
			body_arg = None;
			body_val = quote!(&());
		} else {
			body_arg = Some(quote!(body: &#body_type));
			body_val = quote!(body);
		}
		client_impl_tokens.extend(quote! {
			#[doc = #fn_doc]
			#[allow(clippy::ptr_arg)]
			pub async fn #fn_name(&self, #body_arg) -> ::core::result::Result<(), #fizyr_rpc::Error>
			where
				F: #fizyr_rpc::format::EncodeBody<#body_type>,
			{
				let encoded = F::encode_body(#body_val).map_err(#fizyr_rpc::Error::encode_failed)?;
				self.peer.send_stream(#service_id, encoded).await?;
				::core::result::Result::Ok(())
			}
		})
	}
}