use super::{upb_ExtensionRegistry, upb_MiniTable, Arena, RawArena, RawMessage};
#[repr(C)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum EncodeStatus {
Ok = 0,
OutOfMemory = 1,
MaxDepthExceeded = 2,
MissingRequired = 3,
}
#[repr(C)]
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum DecodeStatus {
Ok = 0,
Malformed = 1,
OutOfMemory = 2,
BadUtf8 = 3,
MaxDepthExceeded = 4,
MissingRequired = 5,
UnlinkedSubMessage = 6,
}
#[repr(i32)]
#[allow(dead_code)]
enum DecodeOption {
AliasString = 1,
CheckRequired = 2,
ExperimentalAllowUnlinked = 4,
AlwaysValidateUtf8 = 8,
}
pub unsafe fn encode(
msg: RawMessage,
mini_table: *const upb_MiniTable,
) -> Result<Vec<u8>, EncodeStatus> {
let arena = Arena::new();
let mut buf: *mut u8 = core::ptr::null_mut();
let mut len = 0usize;
let status = unsafe { upb_Encode(msg, mini_table, 0, arena.raw(), &mut buf, &mut len) };
if status == EncodeStatus::Ok {
assert!(!buf.is_null()); Ok(unsafe { &*core::ptr::slice_from_raw_parts(buf, len) }.to_vec())
} else {
Err(status)
}
}
pub unsafe fn decode(
buf: &[u8],
msg: RawMessage,
mini_table: *const upb_MiniTable,
arena: &Arena,
) -> Result<(), DecodeStatus> {
let len = buf.len();
let buf = buf.as_ptr();
let options = DecodeOption::CheckRequired as i32;
let status =
unsafe { upb_Decode(buf, len, msg, mini_table, core::ptr::null(), options, arena.raw()) };
match status {
DecodeStatus::Ok => Ok(()),
_ => Err(status),
}
}
extern "C" {
pub fn upb_Encode(
msg: RawMessage,
mini_table: *const upb_MiniTable,
options: i32,
arena: RawArena,
buf: *mut *mut u8,
buf_size: *mut usize,
) -> EncodeStatus;
pub fn upb_Decode(
buf: *const u8,
buf_size: usize,
msg: RawMessage,
mini_table: *const upb_MiniTable,
extreg: *const upb_ExtensionRegistry,
options: i32,
arena: RawArena,
) -> DecodeStatus;
}
#[cfg(test)]
mod tests {
use super::*;
use googletest::gtest;
#[gtest]
fn assert_wire_linked() {
use crate::assert_linked;
assert_linked!(upb_Encode);
assert_linked!(upb_Decode);
}
}