|
5 | 5 | // license that can be found in the LICENSE file or at |
6 | 6 | // https://developers.google.com/open-source/licenses/bsd |
7 | 7 |
|
8 | | -use super::sys::text::text::upb_DebugString; |
| 8 | +use super::sys::text::text::{upb_DebugString, upb_TextEncode}; |
9 | 9 | use super::{AssociatedMiniTable, MessagePtr}; |
10 | 10 |
|
11 | 11 | /// Returns a string of field number to value entries of a message. |
@@ -34,3 +34,34 @@ pub unsafe fn debug_string<T: AssociatedMiniTable>(msg: MessagePtr<T>) -> String |
34 | 34 | assert_eq!(len, written_len); |
35 | 35 | String::from_utf8_lossy(buf.as_slice()).to_string() |
36 | 36 | } |
| 37 | + |
| 38 | +/// Encodes a message as text format. |
| 39 | +/// |
| 40 | +/// # Safety |
| 41 | +/// - `msg` must be legally dereferenceable. |
| 42 | +pub unsafe fn text_encode<'pool, T>( |
| 43 | + msg: super::MessagePtr<T>, |
| 44 | + def: &super::MessageDef<'pool>, |
| 45 | + _pool: &'pool super::DefPool, |
| 46 | +) -> String { |
| 47 | + let msg = msg.raw(); |
| 48 | + |
| 49 | + // SAFETY: buf is legally writable if size > 0 (size is 0 here) |
| 50 | + let len = unsafe { |
| 51 | + upb_TextEncode(msg, def.as_ptr(), core::ptr::null(), 0, core::ptr::null_mut(), 0) |
| 52 | + }; |
| 53 | + |
| 54 | + let mut buf = vec![0u8; len + 1]; |
| 55 | + |
| 56 | + // SAFETY: buf is writable for its len |
| 57 | + let written_len = unsafe { |
| 58 | + upb_TextEncode(msg, def.as_ptr(), core::ptr::null(), 0, buf.as_mut_ptr(), buf.len()) |
| 59 | + }; |
| 60 | + |
| 61 | + // upb_TextEncode returns the length excluding NULL, same as len |
| 62 | + assert_eq!(len, written_len); |
| 63 | + |
| 64 | + // Truncate to written length (ignoring NULL) |
| 65 | + buf.truncate(len); |
| 66 | + String::from_utf8_lossy(buf.as_slice()).to_string() |
| 67 | +} |
0 commit comments