proxy_wasm/
hostcalls.rs

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