{% if has_error and is_optional %}
match result {
Ok(Some(val)) => {
// Copy through a `&[u8]` slice so the path works for every byte-ish return shape:
// an owned `Vec<u8>` or `bytes::Bytes`, and equally a *borrowed* `&Bytes`/`&[u8]`
// from an accessor like `fn as_bytes(&self) -> &Bytes`. `Vec::<u8>::from(val)`
// handled only the owned cases -- there is no `From<&Bytes> for Vec<u8>`, so a
// borrowing accessor failed to compile. Indexing with `[..]` derefs uniformly. The
// slice is redundant for the owned shapes and load-bearing for the borrowed ones,
// and this template cannot tell them apart, so the lint is allowed rather than the
// expression narrowed. ~keep
#[allow(clippy::redundant_slicing)]
let buffer = Vec::<u8>::from(&val[..]).into_boxed_slice();
let len = buffer.len();
let ptr = Box::into_raw(buffer).cast::<u8>();
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = ptr; *out_len = len; *out_cap = len; }
0
}
Ok(None) => {
// A null out_ptr is the `None` encoding. `Some(&[])` still writes the
// non-null dangling-but-aligned pointer of an empty boxed slice, so an
// absent value never collides with a present-but-empty one.
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = std::ptr::null_mut(); *out_len = 0; *out_cap = 0; }
0
}
Err(e) => {
set_last_error(alef_ffi_error_code(&e), &e.to_string());
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = std::ptr::null_mut(); *out_len = 0; *out_cap = 0; }
-1
}
}
{% elif is_optional %}
match result {
Some(val) => {
// Copy through a `&[u8]` slice so the path works for every byte-ish return shape:
// an owned `Vec<u8>` or `bytes::Bytes`, and equally a *borrowed* `&Bytes`/`&[u8]`
// from an accessor like `fn as_bytes(&self) -> &Bytes`. `Vec::<u8>::from(val)`
// handled only the owned cases -- there is no `From<&Bytes> for Vec<u8>`, so a
// borrowing accessor failed to compile. Indexing with `[..]` derefs uniformly. The
// slice is redundant for the owned shapes and load-bearing for the borrowed ones,
// and this template cannot tell them apart, so the lint is allowed rather than the
// expression narrowed. ~keep
#[allow(clippy::redundant_slicing)]
let buffer = Vec::<u8>::from(&val[..]).into_boxed_slice();
let len = buffer.len();
let ptr = Box::into_raw(buffer).cast::<u8>();
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = ptr; *out_len = len; *out_cap = len; }
0
}
None => {
// A null out_ptr is the `None` encoding. `Some(&[])` still writes the
// non-null dangling-but-aligned pointer of an empty boxed slice, so an
// absent value never collides with a present-but-empty one.
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = std::ptr::null_mut(); *out_len = 0; *out_cap = 0; }
0
}
}
{% elif has_error %}
match result {
Ok(val) => {
// Copy through a `&[u8]` slice so the path works for every byte-ish return shape:
// an owned `Vec<u8>` or `bytes::Bytes`, and equally a *borrowed* `&Bytes`/`&[u8]`
// from an accessor like `fn as_bytes(&self) -> &Bytes`. `Vec::<u8>::from(val)`
// handled only the owned cases -- there is no `From<&Bytes> for Vec<u8>`, so a
// borrowing accessor failed to compile. Indexing with `[..]` derefs uniformly. The
// slice is redundant for the owned shapes and load-bearing for the borrowed ones,
// and this template cannot tell them apart, so the lint is allowed rather than the
// expression narrowed. ~keep
#[allow(clippy::redundant_slicing)]
let buffer = Vec::<u8>::from(&val[..]).into_boxed_slice();
let len = buffer.len();
let ptr = Box::into_raw(buffer).cast::<u8>();
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = ptr; *out_len = len; *out_cap = len; }
0
}
Err(e) => {
set_last_error(alef_ffi_error_code(&e), &e.to_string());
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = std::ptr::null_mut(); *out_len = 0; *out_cap = 0; }
-1
}
}
{% else %}
// Copy through a `&[u8]` slice so the path works for every byte-ish return shape:
// an owned `Vec<u8>` or `bytes::Bytes`, and equally a *borrowed* `&Bytes`/`&[u8]`
// from an accessor like `fn as_bytes(&self) -> &Bytes`. `Vec::<u8>::from(result)`
// handled only the owned cases -- there is no `From<&Bytes> for Vec<u8>`, so a
// borrowing accessor failed to compile. Indexing with `[..]` derefs uniformly. The
// slice is redundant for the owned shapes and load-bearing for the borrowed ones,
// and this template cannot tell them apart, so the lint is allowed rather than the
// expression narrowed. ~keep
#[allow(clippy::redundant_slicing)]
let buffer = Vec::<u8>::from(&result[..]).into_boxed_slice();
let len = buffer.len();
let ptr = Box::into_raw(buffer).cast::<u8>();
// SAFETY: out_ptr/out_len/out_cap were null-checked above.
unsafe { *out_ptr = ptr; *out_len = len; *out_cap = len; }
0
{% endif %}