use bytes::Bytes;
use std::sync::Arc;
use crate::method::{MethodConfig, MethodResult};
use crate::service::ServiceDefinition;
use crate::transport::{
AraDeserialize, AraSerialize, MessageHeader, MessageType, ReturnCode, Transport,
};
use crate::types::*;
pub struct ProxyBase<T: Transport> {
transport: Arc<T>,
service_id: ServiceId,
instance_id: InstanceId,
method_config: MethodConfig,
}
impl<T: Transport> ProxyBase<T> {
pub fn new(
transport: Arc<T>,
service_id: ServiceId,
instance_id: InstanceId,
method_config: MethodConfig,
) -> Self {
Self {
transport,
service_id,
instance_id,
method_config,
}
}
pub fn with_defaults(
transport: Arc<T>,
service_id: ServiceId,
instance_id: InstanceId,
) -> Self {
Self::new(transport, service_id, instance_id, MethodConfig::default())
}
pub fn transport(&self) -> &Arc<T> {
&self.transport
}
pub fn service_id(&self) -> ServiceId {
self.service_id
}
pub fn instance_id(&self) -> InstanceId {
self.instance_id
}
pub fn method_config(&self) -> &MethodConfig {
&self.method_config
}
pub async fn call_method<Req, Resp>(
&self,
method_id: MethodId,
request: &Req,
) -> MethodResult<Resp>
where
Req: AraSerialize,
Resp: AraDeserialize,
{
let mut buf = Vec::with_capacity(request.serialized_size());
request.ara_serialize(&mut buf)?;
let header = MessageHeader {
service_id: self.service_id,
method_id,
instance_id: self.instance_id,
session_id: 0,
message_type: MessageType::Request,
return_code: ReturnCode::Ok,
};
let (_resp_header, resp_payload) = self
.transport
.send_request(header, Bytes::from(buf))
.await?;
let result = Resp::ara_deserialize(&resp_payload)?;
Ok(result)
}
pub async fn call_fire_and_forget<Req>(
&self,
method_id: MethodId,
request: &Req,
) -> MethodResult<()>
where
Req: AraSerialize,
{
let mut buf = Vec::with_capacity(request.serialized_size());
request.ara_serialize(&mut buf)?;
let header = MessageHeader {
service_id: self.service_id,
method_id,
instance_id: self.instance_id,
session_id: 0,
message_type: MessageType::RequestNoReturn,
return_code: ReturnCode::Ok,
};
self.transport
.send_fire_and_forget(header, Bytes::from(buf))
.await
}
}
pub trait Proxy: Send + Sync {
type ServiceDef: crate::service::ServiceDefinition;
type TransportImpl: Transport;
fn new(transport: Arc<Self::TransportImpl>, instance_id: InstanceId) -> Self;
fn service_id() -> ServiceId {
Self::ServiceDef::SERVICE_ID
}
}