use std::sync::Arc;
use protobuf::well_known_types::wrappers::StringValue;
use up_rust::{
communication::{
CallOptions, InMemoryRpcClient, InMemoryRpcServer, RequestHandler, RpcClient, RpcServer,
ServiceInvocationError, UPayload,
},
local_transport::LocalTransport,
LocalUriProvider, StaticUriProvider, UAttributes,
};
struct EchoOperation {}
#[async_trait::async_trait]
impl RequestHandler for EchoOperation {
async fn handle_request(
&self,
_resource_id: u16,
_message_attributes: &UAttributes,
request_payload: Option<UPayload>,
) -> Result<Option<UPayload>, ServiceInvocationError> {
if let Some(req_payload) = request_payload {
Ok(Some(req_payload))
} else {
Err(ServiceInvocationError::InvalidArgument(
"request has no payload".to_string(),
))
}
}
}
#[tokio::main]
pub async fn main() -> Result<(), Box<dyn std::error::Error>> {
const METHOD_RESOURCE_ID: u16 = 0x00a0;
let uri_provider = Arc::new(StaticUriProvider::new("my-vehicle", 0xa34b, 0x01));
let transport = Arc::new(LocalTransport::default());
let rpc_server = InMemoryRpcServer::new(transport.clone(), uri_provider.clone());
let echo_op = Arc::new(EchoOperation {});
rpc_server
.register_endpoint(None, METHOD_RESOURCE_ID, echo_op.clone())
.await?;
let rpc_client = InMemoryRpcClient::new(transport, uri_provider.clone()).await?;
match rpc_client
.invoke_method(
uri_provider.get_resource_uri(METHOD_RESOURCE_ID),
CallOptions::for_rpc_request(1_000, None, None, None),
None, )
.await
{
Err(ServiceInvocationError::InvalidArgument(msg)) => {
println!("service returned expected error: {msg}")
}
_ => panic!("expected service to return an Invalid Argument error"),
}
let value = StringValue {
value: "Hello".to_string(),
..Default::default()
};
let payload = UPayload::try_from_protobuf(value)?;
match rpc_client
.invoke_method(
uri_provider.get_resource_uri(METHOD_RESOURCE_ID),
CallOptions::for_rpc_request(1_000, None, None, None),
Some(payload),
)
.await
{
Ok(Some(payload)) => {
let value = payload.extract_protobuf::<StringValue>()?;
println!("service returned message: {}", value.value);
}
_ => panic!("expected service to return response message"),
}
rpc_server
.unregister_endpoint(None, METHOD_RESOURCE_ID, echo_op)
.await?;
Ok(())
}