1#[cfg(test)]
16test_r::enable!();
17
18#[allow(clippy::large_enum_variant)]
19pub mod proto {
20 use crate::proto::golem::worker::UpdateMode;
21 use bincode::de::Decoder;
22 use bincode::enc::Encoder;
23 use bincode::error::{DecodeError, EncodeError};
24 use bincode::{Decode, Encode};
25 use golem_wasm_ast::analysis::{
26 AnalysedExport, AnalysedFunction, AnalysedFunctionParameter, AnalysedFunctionResult,
27 AnalysedInstance,
28 };
29 use uuid::Uuid;
30
31 tonic::include_proto!("mod");
32
33 pub const FILE_DESCRIPTOR_SET: &[u8] = tonic::include_file_descriptor_set!("services");
34
35 impl From<Uuid> for golem::common::Uuid {
36 fn from(value: Uuid) -> Self {
37 let (high_bits, low_bits) = value.as_u64_pair();
38 golem::common::Uuid {
39 high_bits,
40 low_bits,
41 }
42 }
43 }
44
45 impl From<golem::common::Uuid> for Uuid {
46 fn from(value: golem::common::Uuid) -> Self {
47 let high_bits = value.high_bits;
48 let low_bits = value.low_bits;
49 Uuid::from_u64_pair(high_bits, low_bits)
50 }
51 }
52
53 impl TryFrom<crate::proto::golem::component::FunctionResult> for AnalysedFunctionResult {
54 type Error = String;
55
56 fn try_from(
57 value: crate::proto::golem::component::FunctionResult,
58 ) -> Result<Self, Self::Error> {
59 Ok(Self {
60 typ: (&value.typ.ok_or("Missing typ")?).try_into()?,
61 })
62 }
63 }
64
65 impl From<AnalysedFunctionResult> for crate::proto::golem::component::FunctionResult {
66 fn from(value: AnalysedFunctionResult) -> Self {
67 Self {
68 typ: Some((&value.typ).into()),
69 }
70 }
71 }
72
73 impl TryFrom<crate::proto::golem::component::ExportInstance> for AnalysedInstance {
74 type Error = String;
75
76 fn try_from(
77 value: crate::proto::golem::component::ExportInstance,
78 ) -> Result<Self, Self::Error> {
79 Ok(Self {
80 name: value.name,
81 functions: value
82 .functions
83 .into_iter()
84 .map(|function| function.try_into())
85 .collect::<Result<_, _>>()?,
86 })
87 }
88 }
89
90 impl From<AnalysedInstance> for crate::proto::golem::component::ExportInstance {
91 fn from(value: AnalysedInstance) -> Self {
92 Self {
93 name: value.name,
94 functions: value
95 .functions
96 .into_iter()
97 .map(|function| function.into())
98 .collect(),
99 }
100 }
101 }
102
103 impl TryFrom<crate::proto::golem::component::ExportFunction> for AnalysedFunction {
104 type Error = String;
105
106 fn try_from(
107 value: crate::proto::golem::component::ExportFunction,
108 ) -> Result<Self, Self::Error> {
109 Ok(Self {
110 name: value.name,
111 parameters: value
112 .parameters
113 .into_iter()
114 .map(|parameter| parameter.try_into())
115 .collect::<Result<_, _>>()?,
116 result: value.result.map(|result| result.try_into()).transpose()?,
117 })
118 }
119 }
120
121 impl From<AnalysedFunction> for crate::proto::golem::component::ExportFunction {
122 fn from(value: AnalysedFunction) -> Self {
123 Self {
124 name: value.name,
125 parameters: value
126 .parameters
127 .into_iter()
128 .map(|parameter| parameter.into())
129 .collect(),
130 result: value.result.map(|result| result.into()),
131 }
132 }
133 }
134
135 impl TryFrom<crate::proto::golem::component::Export> for AnalysedExport {
136 type Error = String;
137
138 fn try_from(value: crate::proto::golem::component::Export) -> Result<Self, Self::Error> {
139 match value.export {
140 None => Err("Missing export".to_string()),
141 Some(crate::proto::golem::component::export::Export::Instance(instance)) => {
142 Ok(Self::Instance(instance.try_into()?))
143 }
144 Some(crate::proto::golem::component::export::Export::Function(function)) => {
145 Ok(Self::Function(function.try_into()?))
146 }
147 }
148 }
149 }
150
151 impl From<AnalysedExport> for crate::proto::golem::component::Export {
152 fn from(value: AnalysedExport) -> Self {
153 match value {
154 AnalysedExport::Instance(instance) => Self {
155 export: Some(crate::proto::golem::component::export::Export::Instance(
156 instance.into(),
157 )),
158 },
159 AnalysedExport::Function(function) => Self {
160 export: Some(crate::proto::golem::component::export::Export::Function(
161 function.into(),
162 )),
163 },
164 }
165 }
166 }
167
168 impl TryFrom<golem::component::FunctionParameter> for AnalysedFunctionParameter {
169 type Error = String;
170
171 fn try_from(
172 value: crate::proto::golem::component::FunctionParameter,
173 ) -> Result<Self, Self::Error> {
174 Ok(Self {
175 name: value.name,
176 typ: (&value.typ.ok_or("Missing typ")?).try_into()?,
177 })
178 }
179 }
180
181 impl From<AnalysedFunctionParameter> for crate::proto::golem::component::FunctionParameter {
182 fn from(value: AnalysedFunctionParameter) -> Self {
183 Self {
184 name: value.name,
185 typ: Some((&value.typ).into()),
186 }
187 }
188 }
189
190 impl Encode for UpdateMode {
191 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
192 match self {
193 UpdateMode::Automatic => 0u8.encode(encoder),
194 UpdateMode::Manual => 1u8.encode(encoder),
195 }
196 }
197 }
198
199 impl<Context> Decode<Context> for UpdateMode {
200 fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
201 match Decode::decode(decoder)? {
202 0u8 => Ok(UpdateMode::Automatic),
203 1u8 => Ok(UpdateMode::Manual),
204 _ => Err(DecodeError::Other("Invalid UpdateMode")),
205 }
206 }
207 }
208
209 #[cfg(test)]
210 mod tests {
211 use crate::proto::golem;
212 use prost::Message;
213 use test_r::test;
214
215 #[test]
216 fn target_worker_id_and_worker_id_are_bin_compatible() {
217 let component_id_uuid = uuid::Uuid::new_v4();
218 let component_id_uuid: golem::common::Uuid = component_id_uuid.into();
219 let component_id = golem::component::ComponentId {
220 value: Some(component_id_uuid),
221 };
222 let target_worker_id = golem::worker::TargetWorkerId {
223 component_id: Some(component_id),
224 name: Some("hello".to_string()),
225 };
226 let worker_id = golem::worker::WorkerId {
227 component_id: Some(component_id),
228 name: "hello".to_string(),
229 };
230
231 let target_worker_id_bytes = target_worker_id.encode_to_vec();
232 let worker_id_bytes = worker_id.encode_to_vec();
233
234 assert_eq!(target_worker_id_bytes, worker_id_bytes);
235 }
236 }
237}