| // Copyright 2026 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef TOOLS_GN_FFI_SLICE_H_ | |
| #define TOOLS_GN_FFI_SLICE_H_ | |
| #include <array> | |
| #include <cstdint> | |
| #include <type_traits> | |
| #include <vector> | |
| #include "gn/ffi/bridge.h" | |
| // Consumes a std::vector<T> to return a Slice to rust. | |
| // This is akin to unique_pointer.release(), where we give up ownership of the | |
| // slice and pass it to rust. | |
| // | |
| // Safety: Rust is *required* to cast this to an OwnedSlice<T>. | |
| // This will guaruntee that the vector is destroyed. | |
| template <typename T> | |
| inline SliceAny IntoSlice(std::vector<T> vec) { | |
| // Rust knows how to free the slice itself (just call free on the pointer), | |
| // but does not know how to call the destructor on individual elements. | |
| static_assert(std::is_trivially_destructible_v<T>, | |
| "T must be trivially destructible to avoid leaks"); | |
| if (vec.empty()) { | |
| return SliceAny{0, nullptr}; | |
| } | |
| SliceAny slice{vec.size(), reinterpret_cast<Any*>(vec.data())}; | |
| // Construct on stack buffer to prevent C++ compiler from running destructor | |
| // on vec | |
| std::array<uint8_t, sizeof(std::vector<T>)> buf; | |
| new (&buf) std::vector<T>(std::move(vec)); | |
| return slice; | |
| } | |
| // Returns a view of a std::vector, which may or may not be const. | |
| // | |
| // Safety: This uses const_cast to cast away constness because SliceAny is a | |
| // unified FFI representation that uses a mutable Any* pointer (which is | |
| // required to support both mutable and immutable slices in Rust). | |
| // | |
| // If the API intends to return immutable objects, the rust caller is | |
| // responsible for wrapping the API in a function that returns Immutable<T>. | |
| template <typename T> | |
| inline SliceAny AsSlice(const std::vector<T>& vec) { | |
| return SliceAny{vec.size(), | |
| reinterpret_cast<Any*>(const_cast<T*>(vec.data()))}; | |
| } | |
| #endif // TOOLS_GN_FFI_SLICE_H_ |