libdd_common/error.rs
1// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4/// A trait to represent a static error message that is represented by both
5/// the requirements of Rust strings and C strings:
6///
7/// 1. It must be a null terminated string with no interior null bytes.
8/// 2. It must be valid UTF-8.
9/// 3. It must not allocate to achieve the static bounds.
10///
11/// Using a c-str literal in Rust achieves all these requirements:
12///
13/// ```
14/// c"this string is compatible with FfiSafeErrorMessage";
15/// ```
16///
17/// # Safety
18///
19/// The strings returned by `as_ffi_str` must be valid UTF-8.
20pub unsafe trait FfiSafeErrorMessage {
21 /// Returns the error message as a static CStr. It must also be a valid
22 /// Rust string, including being UTF-8.
23 fn as_ffi_str(&self) -> &'static std::ffi::CStr;
24
25 /// Returns the error message as a static Rust str, excluding the null
26 /// terminator. If you need it, use [`FfiSafeErrorMessage::as_ffi_str`].
27 ///
28 /// Do not override this method, it would be marked final if it existed.
29 fn as_rust_str(&self) -> &'static str {
30 // Bytes will not contain the null terminator.
31 let bytes = self.as_ffi_str().to_bytes();
32 unsafe { std::str::from_utf8_unchecked(bytes) }
33 }
34}