Skip to main content

ara_com/
proxy.rs

1use bytes::Bytes;
2use std::sync::Arc;
3
4use crate::method::{MethodConfig, MethodResult};
5use crate::service::ServiceDefinition;
6use crate::transport::{
7    AraDeserialize, AraSerialize, MessageHeader, MessageType, ReturnCode, Transport,
8};
9use crate::types::*;
10
11/// Base proxy that generated proxies wrap.
12///
13/// Holds transport, identity, and default method configuration. Generated
14/// proxy structs embed a `ProxyBase<T>` and delegate all wire-level calls to
15/// its helper methods.
16pub struct ProxyBase<T: Transport> {
17    transport: Arc<T>,
18    service_id: ServiceId,
19    instance_id: InstanceId,
20    method_config: MethodConfig,
21}
22
23impl<T: Transport> ProxyBase<T> {
24    /// Create a new `ProxyBase`.
25    pub fn new(
26        transport: Arc<T>,
27        service_id: ServiceId,
28        instance_id: InstanceId,
29        method_config: MethodConfig,
30    ) -> Self {
31        Self {
32            transport,
33            service_id,
34            instance_id,
35            method_config,
36        }
37    }
38
39    /// Create a new `ProxyBase` with default `MethodConfig`.
40    pub fn with_defaults(
41        transport: Arc<T>,
42        service_id: ServiceId,
43        instance_id: InstanceId,
44    ) -> Self {
45        Self::new(transport, service_id, instance_id, MethodConfig::default())
46    }
47
48    /// Accessor for the underlying transport (needed by generated code that
49    /// calls event/field subscription methods directly).
50    pub fn transport(&self) -> &Arc<T> {
51        &self.transport
52    }
53
54    /// The SOME/IP service ID this proxy targets.
55    pub fn service_id(&self) -> ServiceId {
56        self.service_id
57    }
58
59    /// The instance ID this proxy targets.
60    pub fn instance_id(&self) -> InstanceId {
61        self.instance_id
62    }
63
64    /// The default method call configuration (timeout, retries).
65    pub fn method_config(&self) -> &MethodConfig {
66        &self.method_config
67    }
68
69    /// Encode `request`, dispatch it via the transport, then decode the
70    /// response payload into `Resp`.
71    ///
72    /// This is the primary helper used by generated proxy method stubs.
73    pub async fn call_method<Req, Resp>(
74        &self,
75        method_id: MethodId,
76        request: &Req,
77    ) -> MethodResult<Resp>
78    where
79        Req: AraSerialize,
80        Resp: AraDeserialize,
81    {
82        // Serialize the request
83        let mut buf = Vec::with_capacity(request.serialized_size());
84        request.ara_serialize(&mut buf)?;
85
86        let header = MessageHeader {
87            service_id: self.service_id,
88            method_id,
89            instance_id: self.instance_id,
90            session_id: 0,
91            message_type: MessageType::Request,
92            return_code: ReturnCode::Ok,
93        };
94
95        let (_resp_header, resp_payload) = self
96            .transport
97            .send_request(header, Bytes::from(buf))
98            .await?;
99
100        let result = Resp::ara_deserialize(&resp_payload)?;
101        Ok(result)
102    }
103
104    /// Send a fire-and-forget (no-return) method call.
105    pub async fn call_fire_and_forget<Req>(
106        &self,
107        method_id: MethodId,
108        request: &Req,
109    ) -> MethodResult<()>
110    where
111        Req: AraSerialize,
112    {
113        let mut buf = Vec::with_capacity(request.serialized_size());
114        request.ara_serialize(&mut buf)?;
115
116        let header = MessageHeader {
117            service_id: self.service_id,
118            method_id,
119            instance_id: self.instance_id,
120            session_id: 0,
121            message_type: MessageType::RequestNoReturn,
122            return_code: ReturnCode::Ok,
123        };
124
125        self.transport
126            .send_fire_and_forget(header, Bytes::from(buf))
127            .await
128    }
129}
130
131/// Trait that generated proxy structs implement.
132///
133/// Enforces that every proxy knows which service it represents and can be
134/// constructed from a transport + instance ID.
135pub trait Proxy: Send + Sync {
136    type ServiceDef: crate::service::ServiceDefinition;
137    type TransportImpl: Transport;
138
139    fn new(transport: Arc<Self::TransportImpl>, instance_id: InstanceId) -> Self;
140
141    fn service_id() -> ServiceId {
142        Self::ServiceDef::SERVICE_ID
143    }
144}