blob: 6868dedbbef44c324a39048606861fae5b7bd566 [file] [log] [blame]
use super::*;
unsafe extern "C" {
pub fn proto2_rust_RepeatedField_Message_new() -> RawRepeatedField;
pub fn proto2_rust_RepeatedField_Message_free(field: RawRepeatedField);
pub fn proto2_rust_RepeatedField_Message_size(field: RawRepeatedField) -> usize;
pub fn proto2_rust_RepeatedField_Message_get(
field: RawRepeatedField,
index: usize,
) -> RawMessage;
pub fn proto2_rust_RepeatedField_Message_get_mut(
field: RawRepeatedField,
index: usize,
) -> RawMessage;
pub fn proto2_rust_RepeatedField_Message_add(
field: RawRepeatedField,
prototype: RawMessage,
) -> RawMessage;
pub fn proto2_rust_RepeatedField_Message_set(
field: RawRepeatedField,
index: usize,
prototype: RawMessage,
) -> RawMessage;
pub fn proto2_rust_RepeatedField_Message_clear(field: RawRepeatedField);
pub fn proto2_rust_RepeatedField_Message_copy_from(
dst: RawRepeatedField,
src: RawRepeatedField,
);
pub fn proto2_rust_RepeatedField_Message_reserve(field: RawRepeatedField, additional: usize);
}
/// The raw type-erased version of an owned `Repeated`.
#[derive(Debug)]
#[doc(hidden)]
pub struct InnerRepeated {
raw: RawRepeatedField,
}
impl InnerRepeated {
pub fn as_mut(&mut self) -> InnerRepeatedMut<'_> {
InnerRepeatedMut::new(self.raw)
}
pub fn raw(&self) -> RawRepeatedField {
self.raw
}
/// # Safety
/// - `raw` must be a valid `proto2::RepeatedField*` or
/// `proto2::RepeatedPtrField*`.
pub unsafe fn from_raw(raw: RawRepeatedField) -> Self {
Self { raw }
}
}
/// The raw type-erased pointer version of `RepeatedMut`.
///
/// Contains a `proto2::RepeatedField*` or `proto2::RepeatedPtrField*`.
#[derive(Clone, Copy, Debug)]
#[doc(hidden)]
pub struct InnerRepeatedMut<'msg> {
pub(crate) raw: RawRepeatedField,
_phantom: PhantomData<&'msg ()>,
}
impl<'msg> InnerRepeatedMut<'msg> {
#[doc(hidden)]
pub fn new(raw: RawRepeatedField) -> Self {
InnerRepeatedMut { raw, _phantom: PhantomData }
}
}
trait CppTypeConversions: Proxied {
type InsertElemType;
type ElemType;
fn elem_to_view<'msg>(v: Self::ElemType) -> View<'msg, Self>;
fn into_insertelem(v: Self) -> Self::InsertElemType;
}
macro_rules! impl_cpp_type_conversions_for_scalars {
($($t:ty),* $(,)?) => {
$(
impl CppTypeConversions for $t {
type InsertElemType = Self;
type ElemType = Self;
fn elem_to_view<'msg>(v: Self) -> View<'msg, Self> {
v
}
fn into_insertelem(v: Self) -> Self {
v
}
}
)*
}
}
impl_cpp_type_conversions_for_scalars!(i32, u32, i64, u64, f32, f64, bool);
impl CppTypeConversions for ProtoString {
type InsertElemType = CppStdString;
type ElemType = PtrAndLen;
fn elem_to_view<'msg>(v: PtrAndLen) -> View<'msg, ProtoString> {
ptrlen_to_str(v)
}
fn into_insertelem(v: Self) -> CppStdString {
v.into_inner(Private).into_raw()
}
}
impl CppTypeConversions for ProtoBytes {
type InsertElemType = CppStdString;
type ElemType = PtrAndLen;
fn elem_to_view<'msg>(v: Self::ElemType) -> View<'msg, Self> {
ptrlen_to_bytes(v)
}
fn into_insertelem(v: Self) -> CppStdString {
v.into_inner(Private).into_raw()
}
}
unsafe impl<T> Singular for T
where
Self: MutProxied + Message,
for<'a> View<'a, Self>: From<MessageViewInner<'a, Self>> + std::default::Default,
for<'a> Mut<'a, Self>: From<MessageMutInner<'a, Self>>,
{
fn repeated_new(_private: Private) -> Repeated<Self> {
// SAFETY:
// - The thunk returns an unaliased and valid `RepeatedPtrField*`
unsafe {
Repeated::from_inner(
Private,
InnerRepeated::from_raw(proto2_rust_RepeatedField_Message_new()),
)
}
}
unsafe fn repeated_free(_private: Private, f: &mut Repeated<Self>) {
// SAFETY
// - `f.raw()` is a valid `RepeatedPtrField*`.
unsafe { proto2_rust_RepeatedField_Message_free(f.as_view().as_raw(Private)) }
}
fn repeated_len(_private: Private, f: View<Repeated<Self>>) -> usize {
// SAFETY: `f.as_raw()` is a valid `RepeatedPtrField*`.
unsafe { proto2_rust_RepeatedField_Message_size(f.as_raw(Private)) }
}
unsafe fn repeated_set_unchecked(
_private: Private,
mut f: Mut<Repeated<Self>>,
i: usize,
v: impl IntoProxied<Self>,
) {
// SAFETY:
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
// - `i < len(f)` is promised by caller.
// - The second argument below is a valid `const Message&`.
unsafe {
proto2_rust_Message_copy_from(
proto2_rust_RepeatedField_Message_get_mut(f.as_raw(Private), i),
v.into_proxied(Private).get_raw_message(Private),
);
}
}
unsafe fn repeated_get_unchecked(
_private: Private,
f: View<Repeated<Self>>,
i: usize,
) -> View<Self> {
// SAFETY:
// - `f.as_raw()` is a valid `const RepeatedPtrField&`.
// - `i < len(f)` is promised by caller.
let msg = unsafe { proto2_rust_RepeatedField_Message_get(f.as_raw(Private), i) };
let inner = unsafe { MessageViewInner::wrap_raw(msg) };
inner.into()
}
unsafe fn repeated_get_mut_unchecked(
_private: Private,
mut f: Mut<Repeated<Self>>,
i: usize,
) -> Mut<Self> {
// SAFETY:
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
// - `i < len(f)` is promised by caller.
let msg = unsafe { proto2_rust_RepeatedField_Message_get_mut(f.as_raw(Private), i) };
let inner = unsafe { MessageMutInner::wrap_raw(msg) };
inner.into()
}
fn repeated_clear(_private: Private, mut f: Mut<Repeated<Self>>) {
// SAFETY:
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
unsafe { proto2_rust_RepeatedField_Message_clear(f.as_raw(Private)) };
}
fn repeated_push(_private: Private, mut f: Mut<Repeated<Self>>, v: impl IntoProxied<Self>) {
// SAFETY:
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
// - The second argument below is a valid `const Message&`.
unsafe {
let prototype =
<View<Self> as std::default::Default>::default().get_raw_message(Private);
let new_elem = proto2_rust_RepeatedField_Message_add(f.as_raw(Private), prototype);
proto2_rust_Message_copy_from(
new_elem,
v.into_proxied(Private).get_raw_message(Private),
);
}
}
fn repeated_copy_from(
_private: Private,
src: View<Repeated<Self>>,
mut dest: Mut<Repeated<Self>>,
) {
// SAFETY:
// - `dest.as_raw()` is a valid `RepeatedPtrField*`.
// - `src.as_raw()` is a valid `const RepeatedPtrField&`.
unsafe {
proto2_rust_RepeatedField_Message_copy_from(dest.as_raw(Private), src.as_raw(Private));
}
}
fn repeated_reserve(_private: Private, mut f: Mut<Repeated<Self>>, additional: usize) {
// SAFETY:
// - `f.as_raw()` is a valid `RepeatedPtrField*`.
unsafe { proto2_rust_RepeatedField_Message_reserve(f.as_raw(Private), additional) }
}
}
macro_rules! impl_repeated_primitives {
(@impl $($t:ty => [
$new_thunk:ident,
$free_thunk:ident,
$add_thunk:ident,
$size_thunk:ident,
$get_thunk:ident,
$set_thunk:ident,
$clear_thunk:ident,
$copy_from_thunk:ident,
$reserve_thunk:ident $(,)?
]),* $(,)?) => {
$(
unsafe extern "C" {
fn $new_thunk() -> RawRepeatedField;
fn $free_thunk(f: RawRepeatedField);
fn $add_thunk(f: RawRepeatedField, v: <$t as CppTypeConversions>::InsertElemType);
fn $size_thunk(f: RawRepeatedField) -> usize;
fn $get_thunk(
f: RawRepeatedField,
i: usize) -> <$t as CppTypeConversions>::ElemType;
fn $set_thunk(
f: RawRepeatedField,
i: usize,
v: <$t as CppTypeConversions>::InsertElemType);
fn $clear_thunk(f: RawRepeatedField);
fn $copy_from_thunk(src: RawRepeatedField, dst: RawRepeatedField);
fn $reserve_thunk(
f: RawRepeatedField,
additional: usize);
}
unsafe impl Singular for $t {
#[allow(dead_code)]
#[inline]
fn repeated_new(_: Private) -> Repeated<$t> {
Repeated::from_inner(Private, InnerRepeated {
raw: unsafe { $new_thunk() }
})
}
#[allow(dead_code)]
#[inline]
unsafe fn repeated_free(_: Private, f: &mut Repeated<$t>) {
unsafe { $free_thunk(f.as_mut().as_raw(Private)) }
}
#[inline]
fn repeated_len(_private: Private, f: View<Repeated<$t>>) -> usize {
unsafe { $size_thunk(f.as_raw(Private)) }
}
#[inline]
fn repeated_push(_private: Private, mut f: Mut<Repeated<$t>>, v: impl IntoProxied<$t>) {
unsafe { $add_thunk(f.as_raw(Private), <$t as CppTypeConversions>::into_insertelem(v.into_proxied(Private))) }
}
#[inline]
fn repeated_clear(_private: Private, mut f: Mut<Repeated<$t>>) {
unsafe { $clear_thunk(f.as_raw(Private)) }
}
#[inline]
unsafe fn repeated_get_unchecked(_private: Private, f: View<Repeated<$t>>, i: usize) -> View<$t> {
unsafe {
<$t as CppTypeConversions>::elem_to_view(
$get_thunk(f.as_raw(Private), i))
}
}
#[inline]
unsafe fn repeated_set_unchecked(_private: Private, mut f: Mut<Repeated<$t>>, i: usize, v: impl IntoProxied<$t>) {
unsafe { $set_thunk(f.as_raw(Private), i, <$t as CppTypeConversions>::into_insertelem(v.into_proxied(Private))) }
}
#[inline]
fn repeated_copy_from(_private: Private, src: View<Repeated<$t>>, mut dest: Mut<Repeated<$t>>) {
unsafe { $copy_from_thunk(src.as_raw(Private), dest.as_raw(Private)) }
}
#[inline]
fn repeated_reserve(_private: Private, mut f: Mut<Repeated<$t>>, additional: usize) {
unsafe { $reserve_thunk(f.as_raw(Private), additional) }
}
}
)*
};
($($t:ty),* $(,)?) => {
paste!{
impl_repeated_primitives!(@impl $(
$t => [
[< proto2_rust_RepeatedField_ $t _new >],
[< proto2_rust_RepeatedField_ $t _free >],
[< proto2_rust_RepeatedField_ $t _add >],
[< proto2_rust_RepeatedField_ $t _size >],
[< proto2_rust_RepeatedField_ $t _get >],
[< proto2_rust_RepeatedField_ $t _set >],
[< proto2_rust_RepeatedField_ $t _clear >],
[< proto2_rust_RepeatedField_ $t _copy_from >],
[< proto2_rust_RepeatedField_ $t _reserve >],
],
)*);
}
};
}
impl_repeated_primitives!(i32, u32, i64, u64, f32, f64, bool, ProtoString, ProtoBytes);
/// Cast a `RepeatedView<SomeEnum>` to `RepeatedView<c_int>`.
pub fn cast_enum_repeated_view<E: Enum + Singular>(
repeated: RepeatedView<E>,
) -> RepeatedView<c_int> {
// SAFETY: the implementer of `Enum` has promised that this
// raw repeated is a type-erased `proto2::RepeatedField<int>*`.
unsafe { RepeatedView::from_raw(Private, repeated.as_raw(Private)) }
}
/// Cast a `RepeatedMut<SomeEnum>` to `RepeatedMut<c_int>`.
///
/// Writing an unknown value is sound because all enums
/// are representationally open.
pub fn cast_enum_repeated_mut<E: Enum + Singular>(
mut repeated: RepeatedMut<E>,
) -> RepeatedMut<c_int> {
// SAFETY: the implementer of `Enum` has promised that this
// raw repeated is a type-erased `proto2::RepeatedField<int>*`.
unsafe {
RepeatedMut::from_inner(
Private,
InnerRepeatedMut { raw: repeated.as_raw(Private), _phantom: PhantomData },
)
}
}
/// Cast a `RepeatedMut<SomeEnum>` to `RepeatedMut<c_int>` and call
/// repeated_reserve.
pub fn reserve_enum_repeated_mut<E: Enum + Singular>(repeated: RepeatedMut<E>, additional: usize) {
let int_repeated = cast_enum_repeated_mut(repeated);
Singular::repeated_reserve(Private, int_repeated, additional);
}
pub fn new_enum_repeated<E: Enum + Singular>() -> Repeated<E> {
let int_repeated = Repeated::<c_int>::new();
let raw = int_repeated.inner.raw();
std::mem::forget(int_repeated);
unsafe { Repeated::from_inner(Private, InnerRepeated::from_raw(raw)) }
}
/// Cast a `RepeatedMut<SomeEnum>` to `RepeatedMut<c_int>` and call
/// repeated_free.
/// # Safety
/// - The passed in `&mut Repeated<E>` must not be used after this function is
/// called.
pub unsafe fn free_enum_repeated<E: Enum + Singular>(repeated: &mut Repeated<E>) {
unsafe {
let mut int_r: Repeated<c_int> =
Repeated::from_inner(Private, InnerRepeated::from_raw(repeated.inner.raw()));
Singular::repeated_free(Private, &mut int_r);
std::mem::forget(int_r);
}
}