1use crate::dispatcher;
16use crate::types::*;
17use std::ptr::{null, null_mut};
18use std::time::{Duration, SystemTime, UNIX_EPOCH};
19
20#[link(wasm_import_module = "env")]
21extern "C" {
22 fn proxy_log(level: LogLevel, message_data: *const u8, message_size: usize) -> Status;
23}
24
25pub fn log(level: LogLevel, message: &str) -> Result<(), Status> {
26 unsafe {
27 match proxy_log(level, message.as_ptr(), message.len()) {
28 Status::Ok => Ok(()),
29 status => panic!("unexpected status: {}", status as u32),
30 }
31 }
32}
33
34#[link(wasm_import_module = "env")]
35extern "C" {
36 fn proxy_get_log_level(return_level: *mut LogLevel) -> Status;
37}
38
39pub fn get_log_level() -> Result<LogLevel, Status> {
40 let mut return_level: LogLevel = LogLevel::Trace;
41 unsafe {
42 match proxy_get_log_level(&mut return_level) {
43 Status::Ok => Ok(return_level),
44 status => panic!("unexpected status: {}", status as u32),
45 }
46 }
47}
48
49#[link(wasm_import_module = "env")]
50extern "C" {
51 fn proxy_get_current_time_nanoseconds(return_time: *mut u64) -> Status;
52}
53
54pub fn get_current_time() -> Result<SystemTime, Status> {
55 let mut return_time: u64 = 0;
56 unsafe {
57 match proxy_get_current_time_nanoseconds(&mut return_time) {
58 Status::Ok => Ok(UNIX_EPOCH + Duration::from_nanos(return_time)),
59 status => panic!("unexpected status: {}", status as u32),
60 }
61 }
62}
63
64#[link(wasm_import_module = "env")]
65extern "C" {
66 fn proxy_set_tick_period_milliseconds(period: u32) -> Status;
67}
68
69pub fn set_tick_period(period: Duration) -> Result<(), Status> {
70 unsafe {
71 match proxy_set_tick_period_milliseconds(period.as_millis() as u32) {
72 Status::Ok => Ok(()),
73 status => panic!("unexpected status: {}", status as u32),
74 }
75 }
76}
77
78#[link(wasm_import_module = "env")]
79extern "C" {
80 fn proxy_get_buffer_bytes(
81 buffer_type: BufferType,
82 start: usize,
83 max_size: usize,
84 return_buffer_data: *mut *mut u8,
85 return_buffer_size: *mut usize,
86 ) -> Status;
87}
88
89pub fn get_buffer(
90 buffer_type: BufferType,
91 start: usize,
92 max_size: usize,
93) -> Result<Option<Bytes>, Status> {
94 let mut return_data: *mut u8 = null_mut();
95 let mut return_size: usize = 0;
96 unsafe {
97 match proxy_get_buffer_bytes(
98 buffer_type,
99 start,
100 max_size,
101 &mut return_data,
102 &mut return_size,
103 ) {
104 Status::Ok => {
105 if !return_data.is_null() {
106 Ok(Some(Vec::from_raw_parts(
107 return_data,
108 return_size,
109 return_size,
110 )))
111 } else {
112 Ok(None)
113 }
114 }
115 Status::NotFound => Ok(None),
116 status => panic!("unexpected status: {}", status as u32),
117 }
118 }
119}
120
121#[link(wasm_import_module = "env")]
122extern "C" {
123 fn proxy_set_buffer_bytes(
124 buffer_type: BufferType,
125 start: usize,
126 size: usize,
127 buffer_data: *const u8,
128 buffer_size: usize,
129 ) -> Status;
130}
131
132pub fn set_buffer(
133 buffer_type: BufferType,
134 start: usize,
135 size: usize,
136 value: &[u8],
137) -> Result<(), Status> {
138 unsafe {
139 match proxy_set_buffer_bytes(buffer_type, start, size, value.as_ptr(), value.len()) {
140 Status::Ok => Ok(()),
141 status => panic!("unexpected status: {}", status as u32),
142 }
143 }
144}
145
146#[cfg(not(all(test, feature = "mockalloc")))]
147#[link(wasm_import_module = "env")]
148extern "C" {
149 fn proxy_get_header_map_pairs(
150 map_type: MapType,
151 return_map_data: *mut *mut u8,
152 return_map_size: *mut usize,
153 ) -> Status;
154}
155
156#[cfg(all(test, feature = "mockalloc"))]
157fn proxy_get_header_map_pairs(
158 map_type: MapType,
159 return_map_data: *mut *mut u8,
160 return_map_size: *mut usize,
161) -> Status {
162 mocks::proxy_get_header_map_pairs(map_type, return_map_data, return_map_size)
163}
164
165pub fn get_map(map_type: MapType) -> Result<Vec<(String, String)>, Status> {
166 unsafe {
167 let mut return_data: *mut u8 = null_mut();
168 let mut return_size: usize = 0;
169 match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
170 Status::Ok => {
171 if !return_data.is_null() {
172 let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size);
173 Ok(utils::deserialize_map(&serialized_map))
174 } else {
175 Ok(Vec::new())
176 }
177 }
178 status => panic!("unexpected status: {}", status as u32),
179 }
180 }
181}
182
183pub fn get_map_bytes(map_type: MapType) -> Result<Vec<(String, Bytes)>, Status> {
184 unsafe {
185 let mut return_data: *mut u8 = null_mut();
186 let mut return_size: usize = 0;
187 match proxy_get_header_map_pairs(map_type, &mut return_data, &mut return_size) {
188 Status::Ok => {
189 if !return_data.is_null() {
190 let serialized_map = Vec::from_raw_parts(return_data, return_size, return_size);
191 Ok(utils::deserialize_map_bytes(&serialized_map))
192 } else {
193 Ok(Vec::new())
194 }
195 }
196 status => panic!("unexpected status: {}", status as u32),
197 }
198 }
199}
200
201#[link(wasm_import_module = "env")]
202extern "C" {
203 fn proxy_set_header_map_pairs(
204 map_type: MapType,
205 map_data: *const u8,
206 map_size: usize,
207 ) -> Status;
208}
209
210pub fn set_map(map_type: MapType, map: Vec<(&str, &str)>) -> Result<(), Status> {
211 let serialized_map = utils::serialize_map(&map);
212 unsafe {
213 match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
214 Status::Ok => Ok(()),
215 status => panic!("unexpected status: {}", status as u32),
216 }
217 }
218}
219
220pub fn set_map_bytes(map_type: MapType, map: Vec<(&str, &[u8])>) -> Result<(), Status> {
221 let serialized_map = utils::serialize_map_bytes(&map);
222 unsafe {
223 match proxy_set_header_map_pairs(map_type, serialized_map.as_ptr(), serialized_map.len()) {
224 Status::Ok => Ok(()),
225 status => panic!("unexpected status: {}", status as u32),
226 }
227 }
228}
229
230#[link(wasm_import_module = "env")]
231extern "C" {
232 fn proxy_get_header_map_value(
233 map_type: MapType,
234 key_data: *const u8,
235 key_size: usize,
236 return_value_data: *mut *mut u8,
237 return_value_size: *mut usize,
238 ) -> Status;
239}
240
241pub fn get_map_value(map_type: MapType, key: &str) -> Result<Option<String>, Status> {
242 let mut return_data: *mut u8 = null_mut();
243 let mut return_size: usize = 0;
244 unsafe {
245 match proxy_get_header_map_value(
246 map_type,
247 key.as_ptr(),
248 key.len(),
249 &mut return_data,
250 &mut return_size,
251 ) {
252 Status::Ok => {
253 if !return_data.is_null() {
254 Ok(Some(
255 String::from_utf8(Vec::from_raw_parts(
256 return_data,
257 return_size,
258 return_size,
259 ))
260 .unwrap(),
261 ))
262 } else {
263 Ok(Some(String::new()))
264 }
265 }
266 Status::NotFound => Ok(None),
267 status => panic!("unexpected status: {}", status as u32),
268 }
269 }
270}
271
272pub fn get_map_value_bytes(map_type: MapType, key: &str) -> Result<Option<Bytes>, Status> {
273 let mut return_data: *mut u8 = null_mut();
274 let mut return_size: usize = 0;
275 unsafe {
276 match proxy_get_header_map_value(
277 map_type,
278 key.as_ptr(),
279 key.len(),
280 &mut return_data,
281 &mut return_size,
282 ) {
283 Status::Ok => {
284 if !return_data.is_null() {
285 Ok(Some(Vec::from_raw_parts(
286 return_data,
287 return_size,
288 return_size,
289 )))
290 } else {
291 Ok(Some(Vec::new()))
292 }
293 }
294 Status::NotFound => Ok(None),
295 status => panic!("unexpected status: {}", status as u32),
296 }
297 }
298}
299
300#[link(wasm_import_module = "env")]
301extern "C" {
302 fn proxy_remove_header_map_value(
303 map_type: MapType,
304 key_data: *const u8,
305 key_size: usize,
306 ) -> Status;
307}
308
309pub fn remove_map_value(map_type: MapType, key: &str) -> Result<(), Status> {
310 unsafe {
311 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
312 Status::Ok => Ok(()),
313 status => panic!("unexpected status: {}", status as u32),
314 }
315 }
316}
317
318#[link(wasm_import_module = "env")]
319extern "C" {
320 fn proxy_replace_header_map_value(
321 map_type: MapType,
322 key_data: *const u8,
323 key_size: usize,
324 value_data: *const u8,
325 value_size: usize,
326 ) -> Status;
327}
328
329pub fn set_map_value(map_type: MapType, key: &str, value: Option<&str>) -> Result<(), Status> {
330 unsafe {
331 if let Some(value) = value {
332 match proxy_replace_header_map_value(
333 map_type,
334 key.as_ptr(),
335 key.len(),
336 value.as_ptr(),
337 value.len(),
338 ) {
339 Status::Ok => Ok(()),
340 status => panic!("unexpected status: {}", status as u32),
341 }
342 } else {
343 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
344 Status::Ok => Ok(()),
345 status => panic!("unexpected status: {}", status as u32),
346 }
347 }
348 }
349}
350
351pub fn set_map_value_bytes(
352 map_type: MapType,
353 key: &str,
354 value: Option<&[u8]>,
355) -> Result<(), Status> {
356 unsafe {
357 if let Some(value) = value {
358 match proxy_replace_header_map_value(
359 map_type,
360 key.as_ptr(),
361 key.len(),
362 value.as_ptr(),
363 value.len(),
364 ) {
365 Status::Ok => Ok(()),
366 status => panic!("unexpected status: {}", status as u32),
367 }
368 } else {
369 match proxy_remove_header_map_value(map_type, key.as_ptr(), key.len()) {
370 Status::Ok => Ok(()),
371 status => panic!("unexpected status: {}", status as u32),
372 }
373 }
374 }
375}
376
377#[link(wasm_import_module = "env")]
378extern "C" {
379 fn proxy_add_header_map_value(
380 map_type: MapType,
381 key_data: *const u8,
382 key_size: usize,
383 value_data: *const u8,
384 value_size: usize,
385 ) -> Status;
386}
387
388pub fn add_map_value(map_type: MapType, key: &str, value: &str) -> Result<(), Status> {
389 unsafe {
390 match proxy_add_header_map_value(
391 map_type,
392 key.as_ptr(),
393 key.len(),
394 value.as_ptr(),
395 value.len(),
396 ) {
397 Status::Ok => Ok(()),
398 status => panic!("unexpected status: {}", status as u32),
399 }
400 }
401}
402
403pub fn add_map_value_bytes(map_type: MapType, key: &str, value: &[u8]) -> Result<(), Status> {
404 unsafe {
405 match proxy_add_header_map_value(
406 map_type,
407 key.as_ptr(),
408 key.len(),
409 value.as_ptr(),
410 value.len(),
411 ) {
412 Status::Ok => Ok(()),
413 status => panic!("unexpected status: {}", status as u32),
414 }
415 }
416}
417
418#[link(wasm_import_module = "env")]
419extern "C" {
420 fn proxy_get_property(
421 path_data: *const u8,
422 path_size: usize,
423 return_value_data: *mut *mut u8,
424 return_value_size: *mut usize,
425 ) -> Status;
426}
427
428pub fn get_property(path: Vec<&str>) -> Result<Option<Bytes>, Status> {
429 let serialized_path = utils::serialize_property_path(path);
430 let mut return_data: *mut u8 = null_mut();
431 let mut return_size: usize = 0;
432 unsafe {
433 match proxy_get_property(
434 serialized_path.as_ptr(),
435 serialized_path.len(),
436 &mut return_data,
437 &mut return_size,
438 ) {
439 Status::Ok => {
440 if !return_data.is_null() {
441 Ok(Some(Vec::from_raw_parts(
442 return_data,
443 return_size,
444 return_size,
445 )))
446 } else {
447 Ok(None)
448 }
449 }
450 Status::NotFound => Ok(None),
451 Status::SerializationFailure => Err(Status::SerializationFailure),
452 Status::InternalFailure => Err(Status::InternalFailure),
453 status => panic!("unexpected status: {}", status as u32),
454 }
455 }
456}
457
458#[link(wasm_import_module = "env")]
459extern "C" {
460 fn proxy_set_property(
461 path_data: *const u8,
462 path_size: usize,
463 value_data: *const u8,
464 value_size: usize,
465 ) -> Status;
466}
467
468pub fn set_property(path: Vec<&str>, value: Option<&[u8]>) -> Result<(), Status> {
469 let serialized_path = utils::serialize_property_path(path);
470 unsafe {
471 match proxy_set_property(
472 serialized_path.as_ptr(),
473 serialized_path.len(),
474 value.map_or(null(), |value| value.as_ptr()),
475 value.map_or(0, |value| value.len()),
476 ) {
477 Status::Ok => Ok(()),
478 status => panic!("unexpected status: {}", status as u32),
479 }
480 }
481}
482
483#[link(wasm_import_module = "env")]
484extern "C" {
485 fn proxy_get_shared_data(
486 key_data: *const u8,
487 key_size: usize,
488 return_value_data: *mut *mut u8,
489 return_value_size: *mut usize,
490 return_cas: *mut u32,
491 ) -> Status;
492}
493
494pub fn get_shared_data(key: &str) -> Result<(Option<Bytes>, Option<u32>), Status> {
495 let mut return_data: *mut u8 = null_mut();
496 let mut return_size: usize = 0;
497 let mut return_cas: u32 = 0;
498 unsafe {
499 match proxy_get_shared_data(
500 key.as_ptr(),
501 key.len(),
502 &mut return_data,
503 &mut return_size,
504 &mut return_cas,
505 ) {
506 Status::Ok => {
507 let cas = match return_cas {
508 0 => None,
509 cas => Some(cas),
510 };
511 if !return_data.is_null() {
512 Ok((
513 Some(Vec::from_raw_parts(return_data, return_size, return_size)),
514 cas,
515 ))
516 } else {
517 Ok((None, cas))
518 }
519 }
520 Status::NotFound => Ok((None, None)),
521 status => panic!("unexpected status: {}", status as u32),
522 }
523 }
524}
525
526#[link(wasm_import_module = "env")]
527extern "C" {
528 fn proxy_set_shared_data(
529 key_data: *const u8,
530 key_size: usize,
531 value_data: *const u8,
532 value_size: usize,
533 cas: u32,
534 ) -> Status;
535}
536
537pub fn set_shared_data(key: &str, value: Option<&[u8]>, cas: Option<u32>) -> Result<(), Status> {
538 unsafe {
539 match proxy_set_shared_data(
540 key.as_ptr(),
541 key.len(),
542 value.map_or(null(), |value| value.as_ptr()),
543 value.map_or(0, |value| value.len()),
544 cas.unwrap_or(0),
545 ) {
546 Status::Ok => Ok(()),
547 Status::CasMismatch => Err(Status::CasMismatch),
548 status => panic!("unexpected status: {}", status as u32),
549 }
550 }
551}
552
553#[link(wasm_import_module = "env")]
554extern "C" {
555 fn proxy_register_shared_queue(
556 name_data: *const u8,
557 name_size: usize,
558 return_id: *mut u32,
559 ) -> Status;
560}
561
562pub fn register_shared_queue(name: &str) -> Result<u32, Status> {
563 unsafe {
564 let mut return_id: u32 = 0;
565 match proxy_register_shared_queue(name.as_ptr(), name.len(), &mut return_id) {
566 Status::Ok => Ok(return_id),
567 status => panic!("unexpected status: {}", status as u32),
568 }
569 }
570}
571
572#[link(wasm_import_module = "env")]
573extern "C" {
574 fn proxy_resolve_shared_queue(
575 vm_id_data: *const u8,
576 vm_id_size: usize,
577 name_data: *const u8,
578 name_size: usize,
579 return_id: *mut u32,
580 ) -> Status;
581}
582
583pub fn resolve_shared_queue(vm_id: &str, name: &str) -> Result<Option<u32>, Status> {
584 let mut return_id: u32 = 0;
585 unsafe {
586 match proxy_resolve_shared_queue(
587 vm_id.as_ptr(),
588 vm_id.len(),
589 name.as_ptr(),
590 name.len(),
591 &mut return_id,
592 ) {
593 Status::Ok => Ok(Some(return_id)),
594 Status::NotFound => Ok(None),
595 status => panic!("unexpected status: {}", status as u32),
596 }
597 }
598}
599
600#[link(wasm_import_module = "env")]
601extern "C" {
602 fn proxy_dequeue_shared_queue(
603 queue_id: u32,
604 return_value_data: *mut *mut u8,
605 return_value_size: *mut usize,
606 ) -> Status;
607}
608
609pub fn dequeue_shared_queue(queue_id: u32) -> Result<Option<Bytes>, Status> {
610 let mut return_data: *mut u8 = null_mut();
611 let mut return_size: usize = 0;
612 unsafe {
613 match proxy_dequeue_shared_queue(queue_id, &mut return_data, &mut return_size) {
614 Status::Ok => {
615 if !return_data.is_null() {
616 Ok(Some(Vec::from_raw_parts(
617 return_data,
618 return_size,
619 return_size,
620 )))
621 } else {
622 Ok(None)
623 }
624 }
625 Status::Empty => Ok(None),
626 Status::NotFound => Err(Status::NotFound),
627 status => panic!("unexpected status: {}", status as u32),
628 }
629 }
630}
631
632#[link(wasm_import_module = "env")]
633extern "C" {
634 fn proxy_enqueue_shared_queue(
635 queue_id: u32,
636 value_data: *const u8,
637 value_size: usize,
638 ) -> Status;
639}
640
641pub fn enqueue_shared_queue(queue_id: u32, value: Option<&[u8]>) -> Result<(), Status> {
642 unsafe {
643 match proxy_enqueue_shared_queue(
644 queue_id,
645 value.map_or(null(), |value| value.as_ptr()),
646 value.map_or(0, |value| value.len()),
647 ) {
648 Status::Ok => Ok(()),
649 Status::NotFound => Err(Status::NotFound),
650 status => panic!("unexpected status: {}", status as u32),
651 }
652 }
653}
654
655#[link(wasm_import_module = "env")]
656extern "C" {
657 fn proxy_continue_stream(stream_type: StreamType) -> Status;
658}
659
660pub fn resume_downstream() -> Result<(), Status> {
661 unsafe {
662 match proxy_continue_stream(StreamType::Downstream) {
663 Status::Ok => Ok(()),
664 status => panic!("unexpected status: {}", status as u32),
665 }
666 }
667}
668
669pub fn resume_upstream() -> Result<(), Status> {
670 unsafe {
671 match proxy_continue_stream(StreamType::Upstream) {
672 Status::Ok => Ok(()),
673 status => panic!("unexpected status: {}", status as u32),
674 }
675 }
676}
677
678pub fn resume_http_request() -> Result<(), Status> {
679 unsafe {
680 match proxy_continue_stream(StreamType::HttpRequest) {
681 Status::Ok => Ok(()),
682 status => panic!("unexpected status: {}", status as u32),
683 }
684 }
685}
686
687pub fn resume_http_response() -> Result<(), Status> {
688 unsafe {
689 match proxy_continue_stream(StreamType::HttpResponse) {
690 Status::Ok => Ok(()),
691 status => panic!("unexpected status: {}", status as u32),
692 }
693 }
694}
695
696#[link(wasm_import_module = "env")]
697extern "C" {
698 fn proxy_close_stream(stream_type: StreamType) -> Status;
699}
700
701pub fn close_downstream() -> Result<(), Status> {
702 unsafe {
703 match proxy_close_stream(StreamType::Downstream) {
704 Status::Ok => Ok(()),
705 status => panic!("unexpected status: {}", status as u32),
706 }
707 }
708}
709pub fn close_upstream() -> Result<(), Status> {
710 unsafe {
711 match proxy_close_stream(StreamType::Upstream) {
712 Status::Ok => Ok(()),
713 status => panic!("unexpected status: {}", status as u32),
714 }
715 }
716}
717
718pub fn reset_http_request() -> Result<(), Status> {
719 unsafe {
720 match proxy_close_stream(StreamType::HttpRequest) {
721 Status::Ok => Ok(()),
722 status => panic!("unexpected status: {}", status as u32),
723 }
724 }
725}
726
727pub fn reset_http_response() -> Result<(), Status> {
728 unsafe {
729 match proxy_close_stream(StreamType::HttpResponse) {
730 Status::Ok => Ok(()),
731 status => panic!("unexpected status: {}", status as u32),
732 }
733 }
734}
735
736#[link(wasm_import_module = "env")]
737extern "C" {
738 fn proxy_send_local_response(
739 status_code: u32,
740 status_code_details_data: *const u8,
741 status_code_details_size: usize,
742 body_data: *const u8,
743 body_size: usize,
744 headers_data: *const u8,
745 headers_size: usize,
746 grpc_status: i32,
747 ) -> Status;
748}
749
750pub fn send_http_response(
751 status_code: u32,
752 headers: Vec<(&str, &str)>,
753 body: Option<&[u8]>,
754) -> Result<(), Status> {
755 let serialized_headers = utils::serialize_map(&headers);
756 unsafe {
757 match proxy_send_local_response(
758 status_code,
759 null(),
760 0,
761 body.map_or(null(), |body| body.as_ptr()),
762 body.map_or(0, |body| body.len()),
763 serialized_headers.as_ptr(),
764 serialized_headers.len(),
765 -1,
766 ) {
767 Status::Ok => Ok(()),
768 status => panic!("unexpected status: {}", status as u32),
769 }
770 }
771}
772
773pub fn send_grpc_response(
774 grpc_status: GrpcStatusCode,
775 grpc_status_message: Option<&str>,
776 custom_metadata: Vec<(&str, &[u8])>,
777) -> Result<(), Status> {
778 let serialized_custom_metadata = utils::serialize_map_bytes(&custom_metadata);
779 unsafe {
780 match proxy_send_local_response(
781 200,
782 null(),
783 0,
784 grpc_status_message.map_or(null(), |grpc_status_message| grpc_status_message.as_ptr()),
785 grpc_status_message.map_or(0, |grpc_status_message| grpc_status_message.len()),
786 serialized_custom_metadata.as_ptr(),
787 serialized_custom_metadata.len(),
788 grpc_status as i32,
789 ) {
790 Status::Ok => Ok(()),
791 status => panic!("unexpected status: {}", status as u32),
792 }
793 }
794}
795
796#[link(wasm_import_module = "env")]
797extern "C" {
798 fn proxy_http_call(
799 upstream_data: *const u8,
800 upstream_size: usize,
801 headers_data: *const u8,
802 headers_size: usize,
803 body_data: *const u8,
804 body_size: usize,
805 trailers_data: *const u8,
806 trailers_size: usize,
807 timeout: u32,
808 return_token: *mut u32,
809 ) -> Status;
810}
811
812pub fn dispatch_http_call(
813 upstream: &str,
814 headers: Vec<(&str, &str)>,
815 body: Option<&[u8]>,
816 trailers: Vec<(&str, &str)>,
817 timeout: Duration,
818) -> Result<u32, Status> {
819 let serialized_headers = utils::serialize_map(&headers);
820 let serialized_trailers = utils::serialize_map(&trailers);
821 let mut return_token: u32 = 0;
822 unsafe {
823 match proxy_http_call(
824 upstream.as_ptr(),
825 upstream.len(),
826 serialized_headers.as_ptr(),
827 serialized_headers.len(),
828 body.map_or(null(), |body| body.as_ptr()),
829 body.map_or(0, |body| body.len()),
830 serialized_trailers.as_ptr(),
831 serialized_trailers.len(),
832 timeout.as_millis() as u32,
833 &mut return_token,
834 ) {
835 Status::Ok => {
836 dispatcher::register_callout(return_token);
837 Ok(return_token)
838 }
839 Status::BadArgument => Err(Status::BadArgument),
840 Status::InternalFailure => Err(Status::InternalFailure),
841 status => panic!("unexpected status: {}", status as u32),
842 }
843 }
844}
845
846#[link(wasm_import_module = "env")]
847extern "C" {
848 fn proxy_grpc_call(
849 upstream_data: *const u8,
850 upstream_size: usize,
851 service_name_data: *const u8,
852 service_name_size: usize,
853 method_name_data: *const u8,
854 method_name_size: usize,
855 initial_metadata_data: *const u8,
856 initial_metadata_size: usize,
857 message_data_data: *const u8,
858 message_data_size: usize,
859 timeout: u32,
860 return_callout_id: *mut u32,
861 ) -> Status;
862}
863
864pub fn dispatch_grpc_call(
865 upstream_name: &str,
866 service_name: &str,
867 method_name: &str,
868 initial_metadata: Vec<(&str, &[u8])>,
869 message: Option<&[u8]>,
870 timeout: Duration,
871) -> Result<u32, Status> {
872 let mut return_callout_id = 0;
873 let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata);
874 unsafe {
875 match proxy_grpc_call(
876 upstream_name.as_ptr(),
877 upstream_name.len(),
878 service_name.as_ptr(),
879 service_name.len(),
880 method_name.as_ptr(),
881 method_name.len(),
882 serialized_initial_metadata.as_ptr(),
883 serialized_initial_metadata.len(),
884 message.map_or(null(), |message| message.as_ptr()),
885 message.map_or(0, |message| message.len()),
886 timeout.as_millis() as u32,
887 &mut return_callout_id,
888 ) {
889 Status::Ok => {
890 dispatcher::register_grpc_callout(return_callout_id);
891 Ok(return_callout_id)
892 }
893 Status::ParseFailure => Err(Status::ParseFailure),
894 Status::InternalFailure => Err(Status::InternalFailure),
895 status => panic!("unexpected status: {}", status as u32),
896 }
897 }
898}
899
900#[link(wasm_import_module = "env")]
901extern "C" {
902 fn proxy_grpc_stream(
903 upstream_data: *const u8,
904 upstream_size: usize,
905 service_name_data: *const u8,
906 service_name_size: usize,
907 method_name_data: *const u8,
908 method_name_size: usize,
909 initial_metadata_data: *const u8,
910 initial_metadata_size: usize,
911 return_stream_id: *mut u32,
912 ) -> Status;
913}
914
915pub fn open_grpc_stream(
916 upstream_name: &str,
917 service_name: &str,
918 method_name: &str,
919 initial_metadata: Vec<(&str, &[u8])>,
920) -> Result<u32, Status> {
921 let mut return_stream_id = 0;
922 let serialized_initial_metadata = utils::serialize_map_bytes(&initial_metadata);
923 unsafe {
924 match proxy_grpc_stream(
925 upstream_name.as_ptr(),
926 upstream_name.len(),
927 service_name.as_ptr(),
928 service_name.len(),
929 method_name.as_ptr(),
930 method_name.len(),
931 serialized_initial_metadata.as_ptr(),
932 serialized_initial_metadata.len(),
933 &mut return_stream_id,
934 ) {
935 Status::Ok => {
936 dispatcher::register_grpc_stream(return_stream_id);
937 Ok(return_stream_id)
938 }
939 Status::ParseFailure => Err(Status::ParseFailure),
940 Status::InternalFailure => Err(Status::InternalFailure),
941 status => panic!("unexpected status: {}", status as u32),
942 }
943 }
944}
945
946#[link(wasm_import_module = "env")]
947extern "C" {
948 fn proxy_grpc_send(
949 token: u32,
950 message_ptr: *const u8,
951 message_len: usize,
952 end_stream: bool,
953 ) -> Status;
954}
955
956pub fn send_grpc_stream_message(
957 token: u32,
958 message: Option<&[u8]>,
959 end_stream: bool,
960) -> Result<(), Status> {
961 unsafe {
962 match proxy_grpc_send(
963 token,
964 message.map_or(null(), |message| message.as_ptr()),
965 message.map_or(0, |message| message.len()),
966 end_stream,
967 ) {
968 Status::Ok => Ok(()),
969 Status::BadArgument => Err(Status::BadArgument),
970 Status::NotFound => Err(Status::NotFound),
971 status => panic!("unexpected status: {}", status as u32),
972 }
973 }
974}
975
976#[link(wasm_import_module = "env")]
977extern "C" {
978 fn proxy_grpc_cancel(token_id: u32) -> Status;
979}
980
981pub fn cancel_grpc_call(token_id: u32) -> Result<(), Status> {
982 unsafe {
983 match proxy_grpc_cancel(token_id) {
984 Status::Ok => Ok(()),
985 Status::NotFound => Err(Status::NotFound),
986 status => panic!("unexpected status: {}", status as u32),
987 }
988 }
989}
990
991pub fn cancel_grpc_stream(token_id: u32) -> Result<(), Status> {
992 unsafe {
993 match proxy_grpc_cancel(token_id) {
994 Status::Ok => Ok(()),
995 Status::NotFound => Err(Status::NotFound),
996 status => panic!("unexpected status: {}", status as u32),
997 }
998 }
999}
1000
1001#[link(wasm_import_module = "env")]
1002extern "C" {
1003 fn proxy_grpc_close(token_id: u32) -> Status;
1004}
1005
1006pub fn close_grpc_stream(token_id: u32) -> Result<(), Status> {
1007 unsafe {
1008 match proxy_grpc_close(token_id) {
1009 Status::Ok => Ok(()),
1010 Status::NotFound => Err(Status::NotFound),
1011 status => panic!("unexpected status: {}", status as u32),
1012 }
1013 }
1014}
1015
1016#[link(wasm_import_module = "env")]
1017extern "C" {
1018 fn proxy_get_status(
1019 return_code: *mut u32,
1020 return_message_data: *mut *mut u8,
1021 return_message_size: *mut usize,
1022 ) -> Status;
1023}
1024
1025pub fn get_grpc_status() -> Result<(u32, Option<String>), Status> {
1026 let mut return_code: u32 = 0;
1027 let mut return_data: *mut u8 = null_mut();
1028 let mut return_size: usize = 0;
1029 unsafe {
1030 match proxy_get_status(&mut return_code, &mut return_data, &mut return_size) {
1031 Status::Ok => {
1032 if !return_data.is_null() {
1033 Ok((
1034 return_code,
1035 Some(
1036 String::from_utf8(Vec::from_raw_parts(
1037 return_data,
1038 return_size,
1039 return_size,
1040 ))
1041 .unwrap(),
1042 ),
1043 ))
1044 } else {
1045 Ok((return_code, None))
1046 }
1047 }
1048 status => panic!("unexpected status: {}", status as u32),
1049 }
1050 }
1051}
1052
1053#[link(wasm_import_module = "env")]
1054extern "C" {
1055 fn proxy_set_effective_context(context_id: u32) -> Status;
1056}
1057
1058pub fn set_effective_context(context_id: u32) -> Result<(), Status> {
1059 unsafe {
1060 match proxy_set_effective_context(context_id) {
1061 Status::Ok => Ok(()),
1062 Status::BadArgument => Err(Status::BadArgument),
1063 status => panic!("unexpected status: {}", status as u32),
1064 }
1065 }
1066}
1067
1068#[link(wasm_import_module = "env")]
1069extern "C" {
1070 fn proxy_call_foreign_function(
1071 function_name_data: *const u8,
1072 function_name_size: usize,
1073 arguments_data: *const u8,
1074 arguments_size: usize,
1075 results_data: *mut *mut u8,
1076 results_size: *mut usize,
1077 ) -> Status;
1078}
1079
1080pub fn call_foreign_function(
1081 function_name: &str,
1082 arguments: Option<&[u8]>,
1083) -> Result<Option<Bytes>, Status> {
1084 let mut return_data: *mut u8 = null_mut();
1085 let mut return_size: usize = 0;
1086 unsafe {
1087 match proxy_call_foreign_function(
1088 function_name.as_ptr(),
1089 function_name.len(),
1090 arguments.map_or(null(), |arguments| arguments.as_ptr()),
1091 arguments.map_or(0, |arguments| arguments.len()),
1092 &mut return_data,
1093 &mut return_size,
1094 ) {
1095 Status::Ok => {
1096 if !return_data.is_null() {
1097 Ok(Some(Vec::from_raw_parts(
1098 return_data,
1099 return_size,
1100 return_size,
1101 )))
1102 } else {
1103 Ok(None)
1104 }
1105 }
1106 Status::NotFound => Err(Status::NotFound),
1107 Status::BadArgument => Err(Status::BadArgument),
1108 Status::SerializationFailure => Err(Status::SerializationFailure),
1109 Status::InternalFailure => Err(Status::InternalFailure),
1110 status => panic!("unexpected status: {}", status as u32),
1111 }
1112 }
1113}
1114
1115#[link(wasm_import_module = "env")]
1116extern "C" {
1117 fn proxy_done() -> Status;
1118}
1119
1120pub fn done() -> Result<(), Status> {
1121 unsafe {
1122 match proxy_done() {
1123 Status::Ok => Ok(()),
1124 status => panic!("unexpected status: {}", status as u32),
1125 }
1126 }
1127}
1128
1129#[link(wasm_import_module = "env")]
1130extern "C" {
1131 fn proxy_define_metric(
1132 metric_type: MetricType,
1133 name_data: *const u8,
1134 name_size: usize,
1135 return_id: *mut u32,
1136 ) -> Status;
1137}
1138
1139pub fn define_metric(metric_type: MetricType, name: &str) -> Result<u32, Status> {
1140 let mut return_id: u32 = 0;
1141 unsafe {
1142 match proxy_define_metric(metric_type, name.as_ptr(), name.len(), &mut return_id) {
1143 Status::Ok => Ok(return_id),
1144 status => panic!("unexpected status: {}", status as u32),
1145 }
1146 }
1147}
1148
1149#[link(wasm_import_module = "env")]
1150extern "C" {
1151 fn proxy_get_metric(metric_id: u32, return_value: *mut u64) -> Status;
1152}
1153
1154pub fn get_metric(metric_id: u32) -> Result<u64, Status> {
1155 let mut return_value: u64 = 0;
1156 unsafe {
1157 match proxy_get_metric(metric_id, &mut return_value) {
1158 Status::Ok => Ok(return_value),
1159 Status::NotFound => Err(Status::NotFound),
1160 Status::BadArgument => Err(Status::BadArgument),
1161 status => panic!("unexpected status: {}", status as u32),
1162 }
1163 }
1164}
1165
1166#[link(wasm_import_module = "env")]
1167extern "C" {
1168 fn proxy_record_metric(metric_id: u32, value: u64) -> Status;
1169}
1170
1171pub fn record_metric(metric_id: u32, value: u64) -> Result<(), Status> {
1172 unsafe {
1173 match proxy_record_metric(metric_id, value) {
1174 Status::Ok => Ok(()),
1175 Status::NotFound => Err(Status::NotFound),
1176 status => panic!("unexpected status: {}", status as u32),
1177 }
1178 }
1179}
1180
1181#[link(wasm_import_module = "env")]
1182extern "C" {
1183 fn proxy_increment_metric(metric_id: u32, offset: i64) -> Status;
1184}
1185
1186pub fn increment_metric(metric_id: u32, offset: i64) -> Result<(), Status> {
1187 unsafe {
1188 match proxy_increment_metric(metric_id, offset) {
1189 Status::Ok => Ok(()),
1190 Status::NotFound => Err(Status::NotFound),
1191 Status::BadArgument => Err(Status::BadArgument),
1192 status => panic!("unexpected status: {}", status as u32),
1193 }
1194 }
1195}
1196
1197#[cfg(all(test, feature = "mockalloc"))]
1198mod mocks {
1199 use crate::hostcalls::utils::tests::SERIALIZED_MAP;
1200 use crate::types::*;
1201 use std::alloc::{alloc, Layout};
1202
1203 pub fn proxy_get_header_map_pairs(
1204 _map_type: MapType,
1205 return_map_data: *mut *mut u8,
1206 return_map_size: *mut usize,
1207 ) -> Status {
1208 let layout = Layout::array::<u8>(SERIALIZED_MAP.len()).unwrap();
1209 unsafe {
1210 *return_map_data = alloc(layout);
1211 *return_map_size = SERIALIZED_MAP.len();
1212 std::ptr::copy(
1213 SERIALIZED_MAP.as_ptr(),
1214 *return_map_data,
1215 SERIALIZED_MAP.len(),
1216 );
1217 }
1218 Status::Ok
1219 }
1220}
1221
1222#[cfg(all(test, feature = "mockalloc"))]
1223mod tests {
1224 use crate::types::*;
1225 use mockalloc::Mockalloc;
1226 use std::alloc::System;
1227
1228 #[global_allocator]
1229 static ALLOCATOR: Mockalloc<System> = Mockalloc(System);
1230
1231 #[mockalloc::test]
1232 fn test_get_map_no_leaks() {
1233 let result = super::get_map(MapType::HttpRequestHeaders);
1234 assert!(result.is_ok());
1235 }
1236
1237 #[mockalloc::test]
1238 fn test_get_map_bytes_no_leaks() {
1239 let result = super::get_map_bytes(MapType::HttpRequestHeaders);
1240 assert!(result.is_ok());
1241 }
1242}
1243
1244mod utils {
1245 use crate::types::Bytes;
1246 use std::convert::TryFrom;
1247
1248 pub(super) fn serialize_property_path(path: Vec<&str>) -> Bytes {
1249 if path.is_empty() {
1250 return Vec::new();
1251 }
1252 let mut size: usize = 0;
1253 for part in &path {
1254 size += part.len() + 1;
1255 }
1256 let mut bytes: Bytes = Vec::with_capacity(size);
1257 for part in &path {
1258 bytes.extend_from_slice(part.as_bytes());
1259 bytes.push(0);
1260 }
1261 bytes.pop();
1262 bytes
1263 }
1264
1265 pub(super) fn serialize_map(map: &[(&str, &str)]) -> Bytes {
1266 let mut size: usize = 4;
1267 for (name, value) in map {
1268 size += name.len() + value.len() + 10;
1269 }
1270 let mut bytes: Bytes = Vec::with_capacity(size);
1271 bytes.extend_from_slice(&(map.len() as u32).to_le_bytes());
1272 for (name, value) in map {
1273 bytes.extend_from_slice(&(name.len() as u32).to_le_bytes());
1274 bytes.extend_from_slice(&(value.len() as u32).to_le_bytes());
1275 }
1276 for (name, value) in map {
1277 bytes.extend_from_slice(name.as_bytes());
1278 bytes.push(0);
1279 bytes.extend_from_slice(value.as_bytes());
1280 bytes.push(0);
1281 }
1282 bytes
1283 }
1284
1285 pub(super) fn serialize_map_bytes(map: &[(&str, &[u8])]) -> Bytes {
1286 let mut size: usize = 4;
1287 for (name, value) in map {
1288 size += name.len() + value.len() + 10;
1289 }
1290 let mut bytes: Bytes = Vec::with_capacity(size);
1291 bytes.extend_from_slice(&(map.len() as u32).to_le_bytes());
1292 for (name, value) in map {
1293 bytes.extend_from_slice(&(name.len() as u32).to_le_bytes());
1294 bytes.extend_from_slice(&(value.len() as u32).to_le_bytes());
1295 }
1296 for (name, value) in map {
1297 bytes.extend_from_slice(name.as_bytes());
1298 bytes.push(0);
1299 bytes.extend_from_slice(value);
1300 bytes.push(0);
1301 }
1302 bytes
1303 }
1304
1305 pub(super) fn deserialize_map(bytes: &[u8]) -> Vec<(String, String)> {
1306 if bytes.is_empty() {
1307 return Vec::new();
1308 }
1309 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[0..4]).unwrap()) as usize;
1310 let mut map = Vec::with_capacity(size);
1311 let mut p = 4 + size * 8;
1312 for n in 0..size {
1313 let s = 4 + n * 8;
1314 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s..s + 4]).unwrap()) as usize;
1315 let key = bytes[p..p + size].to_vec();
1316 p += size + 1;
1317 let size =
1318 u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s + 4..s + 8]).unwrap()) as usize;
1319 let value = bytes[p..p + size].to_vec();
1320 p += size + 1;
1321 map.push((
1322 String::from_utf8(key).unwrap(),
1323 String::from_utf8(value).unwrap(),
1324 ));
1325 }
1326 map
1327 }
1328
1329 pub(super) fn deserialize_map_bytes(bytes: &[u8]) -> Vec<(String, Bytes)> {
1330 if bytes.is_empty() {
1331 return Vec::new();
1332 }
1333 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[0..4]).unwrap()) as usize;
1334 let mut map = Vec::with_capacity(size);
1335 let mut p = 4 + size * 8;
1336 for n in 0..size {
1337 let s = 4 + n * 8;
1338 let size = u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s..s + 4]).unwrap()) as usize;
1339 let key = bytes[p..p + size].to_vec();
1340 p += size + 1;
1341 let size =
1342 u32::from_le_bytes(<[u8; 4]>::try_from(&bytes[s + 4..s + 8]).unwrap()) as usize;
1343 let value = bytes[p..p + size].to_vec();
1344 p += size + 1;
1345 map.push((String::from_utf8(key).unwrap(), value));
1346 }
1347 map
1348 }
1349
1350 #[cfg(test)]
1351 pub(super) mod tests {
1352 use super::*;
1353
1354 #[cfg(nightly)]
1355 use test::Bencher;
1356
1357 static MAP: &[(&str, &str)] = &[
1358 (":method", "GET"),
1359 (":path", "/bytes/1"),
1360 (":authority", "httpbin.org"),
1361 ("Powered-By", "proxy-wasm"),
1362 ];
1363
1364 #[rustfmt::skip]
1365 pub(in crate::hostcalls) static SERIALIZED_MAP: &[u8] = &[
1366 4, 0, 0, 0,
1368 7, 0, 0, 0, 3, 0, 0, 0,
1370 5, 0, 0, 0, 8, 0, 0, 0,
1372 10, 0, 0, 0, 11, 0, 0, 0,
1374 10, 0, 0, 0, 10, 0, 0, 0,
1376 58, 109, 101, 116, 104, 111, 100, 0,
1378 71, 69, 84, 0,
1380 58, 112, 97, 116, 104, 0,
1382 47, 98, 121, 116, 101, 115, 47, 49, 0,
1384 58, 97, 117, 116, 104, 111, 114, 105, 116, 121, 0,
1386 104, 116, 116, 112, 98, 105, 110, 46, 111, 114, 103, 0,
1388 80, 111, 119, 101, 114, 101, 100, 45, 66, 121, 0,
1390 112, 114, 111, 120, 121, 45, 119, 97, 115, 109, 0,
1392 ];
1393
1394 #[test]
1395 fn test_serialize_map_empty() {
1396 let serialized_map = serialize_map(&[]);
1397 assert_eq!(serialized_map, [0, 0, 0, 0]);
1398 }
1399
1400 #[test]
1401 fn test_serialize_map_empty_bytes() {
1402 let serialized_map = serialize_map_bytes(&[]);
1403 assert_eq!(serialized_map, [0, 0, 0, 0]);
1404 }
1405
1406 #[test]
1407 fn test_deserialize_map_empty() {
1408 let map = deserialize_map(&[]);
1409 assert_eq!(map, []);
1410 let map = deserialize_map(&[0, 0, 0, 0]);
1411 assert_eq!(map, []);
1412 }
1413
1414 #[test]
1415 fn test_deserialize_map_empty_bytes() {
1416 let map = deserialize_map_bytes(&[]);
1417 assert_eq!(map, []);
1418 let map = deserialize_map_bytes(&[0, 0, 0, 0]);
1419 assert_eq!(map, []);
1420 }
1421
1422 #[test]
1423 fn test_serialize_map() {
1424 let serialized_map = serialize_map(MAP);
1425 assert_eq!(serialized_map, SERIALIZED_MAP);
1426 }
1427
1428 #[test]
1429 fn test_serialize_map_bytes() {
1430 let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect();
1431 let serialized_map = serialize_map_bytes(&map);
1432 assert_eq!(serialized_map, SERIALIZED_MAP);
1433 }
1434
1435 #[test]
1436 fn test_deserialize_map() {
1437 let map = deserialize_map(SERIALIZED_MAP);
1438 assert_eq!(map.len(), MAP.len());
1439 for (got, expected) in map.into_iter().zip(MAP) {
1440 assert_eq!(got.0, expected.0);
1441 assert_eq!(got.1, expected.1);
1442 }
1443 }
1444
1445 #[test]
1446 fn test_deserialize_map_bytes() {
1447 let map = deserialize_map_bytes(SERIALIZED_MAP);
1448 assert_eq!(map.len(), MAP.len());
1449 for (got, expected) in map.into_iter().zip(MAP) {
1450 assert_eq!(got.0, expected.0);
1451 assert_eq!(got.1, expected.1.as_bytes());
1452 }
1453 }
1454
1455 #[test]
1456 fn test_deserialize_map_roundtrip() {
1457 let map = deserialize_map(SERIALIZED_MAP);
1458 let map_refs: Vec<(&str, &str)> =
1460 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1461 let serialized_map = serialize_map(&map_refs);
1462 assert_eq!(serialized_map, SERIALIZED_MAP);
1463 }
1464
1465 #[test]
1466 fn test_deserialize_map_roundtrip_bytes() {
1467 let map = deserialize_map_bytes(SERIALIZED_MAP);
1468 let map_refs: Vec<(&str, &[u8])> =
1470 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1471 let serialized_map = serialize_map_bytes(&map_refs);
1472 assert_eq!(serialized_map, SERIALIZED_MAP);
1473 }
1474
1475 #[test]
1476 fn test_deserialize_map_all_chars() {
1477 for i in 0..0x7f {
1479 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1480 let map = deserialize_map(&serialized_src);
1481 let map_refs: Vec<(&str, &str)> =
1483 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1484 let serialized_map = serialize_map(&map_refs);
1485 assert_eq!(serialized_map, serialized_src);
1486 }
1487 for i in 0x80..0xff {
1489 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1490 std::panic::set_hook(Box::new(|_| {}));
1491 let result = std::panic::catch_unwind(|| {
1492 deserialize_map(&serialized_src);
1493 });
1494 assert!(result.is_err());
1495 }
1496 }
1497
1498 #[test]
1499 fn test_deserialize_map_all_chars_bytes() {
1500 for i in 0..0xff {
1502 let serialized_src = [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 99, 0, i, 0];
1503 let map = deserialize_map_bytes(&serialized_src);
1504 let map_refs: Vec<(&str, &[u8])> =
1506 map.iter().map(|x| (x.0.as_ref(), x.1.as_ref())).collect();
1507 let serialized_map = serialize_map_bytes(&map_refs);
1508 assert_eq!(serialized_map, serialized_src);
1509 }
1510 }
1511
1512 #[cfg(nightly)]
1513 #[bench]
1514 fn bench_serialize_map(b: &mut Bencher) {
1515 let map = MAP.to_vec();
1516 b.iter(|| {
1517 serialize_map(test::black_box(&map));
1518 });
1519 }
1520
1521 #[cfg(nightly)]
1522 #[bench]
1523 fn bench_serialize_map_bytes(b: &mut Bencher) {
1524 let map: Vec<(&str, &[u8])> = MAP.iter().map(|x| (x.0, x.1.as_bytes())).collect();
1525 b.iter(|| {
1526 serialize_map_bytes(test::black_box(&map));
1527 });
1528 }
1529
1530 #[cfg(nightly)]
1531 #[bench]
1532 fn bench_deserialize_map(b: &mut Bencher) {
1533 let serialized_map = SERIALIZED_MAP.to_vec();
1534 b.iter(|| {
1535 deserialize_map(test::black_box(&serialized_map));
1536 });
1537 }
1538
1539 #[cfg(nightly)]
1540 #[bench]
1541 fn bench_deserialize_map_bytes(b: &mut Bencher) {
1542 let serialized_map = SERIALIZED_MAP.to_vec();
1543 b.iter(|| {
1544 deserialize_map_bytes(test::black_box(&serialized_map));
1545 });
1546 }
1547 }
1548}