blob: afddb42c17954ec9fd510f5129d0e156dac0c2a7 [file] [log] [blame]
Protobuf Team Bot219e8ea2024-06-28 05:51:01 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2024 Google LLC. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
Protobuf Team Bot607b4b12024-07-23 10:28:15 -07008use super::opaque_pointee::opaque_pointee;
9use super::{upb_MessageValue, CType, RawArena};
Protobuf Team Botb35d4ba2024-09-06 13:04:52 -070010use core::ptr::NonNull;
Protobuf Team Botd44ba902024-04-16 08:05:40 -070011
12opaque_pointee!(upb_Map);
13pub type RawMap = NonNull<upb_Map>;
14
15#[repr(C)]
16#[allow(dead_code)]
17#[derive(PartialEq, Eq, Clone, Copy, Debug)]
18pub enum MapInsertStatus {
19 Inserted = 0,
20 Replaced = 1,
21 OutOfMemory = 2,
22}
23
Derek Benson1e1bf0d2024-07-26 11:07:22 -070024pub const UPB_MAP_BEGIN: usize = usize::MAX;
Protobuf Team Botd44ba902024-04-16 08:05:40 -070025
Derek Benson1e1bf0d2024-07-26 11:07:22 -070026extern "C" {
Protobuf Team Botd44ba902024-04-16 08:05:40 -070027 pub fn upb_Map_New(arena: RawArena, key_type: CType, value_type: CType) -> RawMap;
28 pub fn upb_Map_Size(map: RawMap) -> usize;
29 pub fn upb_Map_Insert(
30 map: RawMap,
31 key: upb_MessageValue,
32 value: upb_MessageValue,
33 arena: RawArena,
34 ) -> MapInsertStatus;
35 pub fn upb_Map_Get(map: RawMap, key: upb_MessageValue, value: *mut upb_MessageValue) -> bool;
36 pub fn upb_Map_Delete(
37 map: RawMap,
38 key: upb_MessageValue,
39 removed_value: *mut upb_MessageValue,
40 ) -> bool;
41 pub fn upb_Map_Clear(map: RawMap);
42 pub fn upb_Map_Next(
43 map: RawMap,
44 key: *mut upb_MessageValue,
45 value: *mut upb_MessageValue,
46 iter: &mut usize,
47 ) -> bool;
48}
49
50#[cfg(test)]
51mod tests {
Protobuf Team Bot607b4b12024-07-23 10:28:15 -070052 use super::super::Arena;
Protobuf Team Botd44ba902024-04-16 08:05:40 -070053 use super::*;
Derek Benson0f4bfc42024-09-10 08:26:29 -070054 use googletest::gtest;
Protobuf Team Botd44ba902024-04-16 08:05:40 -070055
Derek Benson0f4bfc42024-09-10 08:26:29 -070056 #[gtest]
Derek Bensona0f79eb2024-09-09 13:27:05 -070057 fn assert_map_linked() {
Derek Benson4c38e112024-09-12 07:57:49 -070058 use crate::assert_linked;
Derek Bensona0f79eb2024-09-09 13:27:05 -070059 assert_linked!(upb_Map_New);
60 assert_linked!(upb_Map_Size);
61 assert_linked!(upb_Map_Insert);
62 assert_linked!(upb_Map_Get);
63 assert_linked!(upb_Map_Delete);
64 assert_linked!(upb_Map_Clear);
65 assert_linked!(upb_Map_Next);
66 }
67
Derek Benson0f4bfc42024-09-10 08:26:29 -070068 #[gtest]
Protobuf Team Botd44ba902024-04-16 08:05:40 -070069 fn map_ffi_test() {
70 // SAFETY: FFI unit test uses C API under expected patterns.
71 unsafe {
Protobuf Team Bot607b4b12024-07-23 10:28:15 -070072 let arena = Arena::new();
Protobuf Team Botd44ba902024-04-16 08:05:40 -070073 let raw_arena = arena.raw();
74 let map = upb_Map_New(raw_arena, CType::Bool, CType::Double);
75 assert_eq!(upb_Map_Size(map), 0);
76 assert_eq!(
77 upb_Map_Insert(
78 map,
79 upb_MessageValue { bool_val: true },
80 upb_MessageValue { double_val: 2.0 },
81 raw_arena
82 ),
83 MapInsertStatus::Inserted
84 );
85 assert_eq!(
86 upb_Map_Insert(
87 map,
88 upb_MessageValue { bool_val: true },
89 upb_MessageValue { double_val: 3.0 },
90 raw_arena,
91 ),
92 MapInsertStatus::Replaced,
93 );
94 assert_eq!(upb_Map_Size(map), 1);
95 upb_Map_Clear(map);
96 assert_eq!(upb_Map_Size(map), 0);
97 assert_eq!(
98 upb_Map_Insert(
99 map,
100 upb_MessageValue { bool_val: true },
101 upb_MessageValue { double_val: 4.0 },
102 raw_arena
103 ),
104 MapInsertStatus::Inserted
105 );
106
107 let mut out = upb_MessageValue::zeroed();
108 assert!(upb_Map_Get(map, upb_MessageValue { bool_val: true }, &mut out));
Protobuf Team Bot0a7691e2024-11-11 14:44:52 -0800109 assert_eq!(out.double_val, 4.0);
Protobuf Team Botd44ba902024-04-16 08:05:40 -0700110 }
111 }
112}