Skip to main content

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}