Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
3.4 KiB
111 lines
3.4 KiB
// Protocol Buffers - Google's data interchange format |
|
// Copyright 2024 Google LLC. All rights reserved. |
|
// |
|
// Use of this source code is governed by a BSD-style |
|
// license that can be found in the LICENSE file or at |
|
// https://developers.google.com/open-source/licenses/bsd |
|
|
|
use super::opaque_pointee::opaque_pointee; |
|
use super::{upb_MessageValue, CType, RawArena}; |
|
use core::ptr::NonNull; |
|
|
|
opaque_pointee!(upb_Map); |
|
pub type RawMap = NonNull<upb_Map>; |
|
|
|
#[repr(C)] |
|
#[allow(dead_code)] |
|
#[derive(PartialEq, Eq, Clone, Copy, Debug)] |
|
pub enum MapInsertStatus { |
|
Inserted = 0, |
|
Replaced = 1, |
|
OutOfMemory = 2, |
|
} |
|
|
|
pub const UPB_MAP_BEGIN: usize = usize::MAX; |
|
|
|
extern "C" { |
|
pub fn upb_Map_New(arena: RawArena, key_type: CType, value_type: CType) -> RawMap; |
|
pub fn upb_Map_Size(map: RawMap) -> usize; |
|
pub fn upb_Map_Insert( |
|
map: RawMap, |
|
key: upb_MessageValue, |
|
value: upb_MessageValue, |
|
arena: RawArena, |
|
) -> MapInsertStatus; |
|
pub fn upb_Map_Get(map: RawMap, key: upb_MessageValue, value: *mut upb_MessageValue) -> bool; |
|
pub fn upb_Map_Delete( |
|
map: RawMap, |
|
key: upb_MessageValue, |
|
removed_value: *mut upb_MessageValue, |
|
) -> bool; |
|
pub fn upb_Map_Clear(map: RawMap); |
|
pub fn upb_Map_Next( |
|
map: RawMap, |
|
key: *mut upb_MessageValue, |
|
value: *mut upb_MessageValue, |
|
iter: &mut usize, |
|
) -> bool; |
|
} |
|
|
|
#[cfg(test)] |
|
mod tests { |
|
use super::super::Arena; |
|
use super::*; |
|
|
|
#[test] |
|
fn assert_map_linked() { |
|
use super::super::assert_linked; |
|
assert_linked!(upb_Map_New); |
|
assert_linked!(upb_Map_Size); |
|
assert_linked!(upb_Map_Insert); |
|
assert_linked!(upb_Map_Get); |
|
assert_linked!(upb_Map_Delete); |
|
assert_linked!(upb_Map_Clear); |
|
assert_linked!(upb_Map_Next); |
|
} |
|
|
|
#[test] |
|
fn map_ffi_test() { |
|
// SAFETY: FFI unit test uses C API under expected patterns. |
|
unsafe { |
|
let arena = Arena::new(); |
|
let raw_arena = arena.raw(); |
|
let map = upb_Map_New(raw_arena, CType::Bool, CType::Double); |
|
assert_eq!(upb_Map_Size(map), 0); |
|
assert_eq!( |
|
upb_Map_Insert( |
|
map, |
|
upb_MessageValue { bool_val: true }, |
|
upb_MessageValue { double_val: 2.0 }, |
|
raw_arena |
|
), |
|
MapInsertStatus::Inserted |
|
); |
|
assert_eq!( |
|
upb_Map_Insert( |
|
map, |
|
upb_MessageValue { bool_val: true }, |
|
upb_MessageValue { double_val: 3.0 }, |
|
raw_arena, |
|
), |
|
MapInsertStatus::Replaced, |
|
); |
|
assert_eq!(upb_Map_Size(map), 1); |
|
upb_Map_Clear(map); |
|
assert_eq!(upb_Map_Size(map), 0); |
|
assert_eq!( |
|
upb_Map_Insert( |
|
map, |
|
upb_MessageValue { bool_val: true }, |
|
upb_MessageValue { double_val: 4.0 }, |
|
raw_arena |
|
), |
|
MapInsertStatus::Inserted |
|
); |
|
|
|
let mut out = upb_MessageValue::zeroed(); |
|
assert!(upb_Map_Get(map, upb_MessageValue { bool_val: true }, &mut out)); |
|
assert!(matches!(out, upb_MessageValue { double_val: 4.0 })); |
|
} |
|
} |
|
}
|
|
|