15#ifndef ACTIONENGINE_PYBIND11_ACTIONENGINE_DATA_H_ 
   16#define ACTIONENGINE_PYBIND11_ACTIONENGINE_DATA_H_ 
   20#include <pybind11/pybind11.h> 
   21#include <pybind11/stl.h> 
   22#include <pybind11/stl_bind.h> 
   23#include <pybind11_abseil/status_caster.h> 
   24#include <pybind11_abseil/statusor_caster.h> 
   26#include "actionengine/data/serialization.h" 
   28#include "actionengine/util/status_macros.h" 
   30PYBIND11_MAKE_OPAQUE(std::vector<act::Port>);
 
   31PYBIND11_MAKE_OPAQUE(std::vector<act::NodeFragment>);
 
   32PYBIND11_MAKE_OPAQUE(std::vector<act::ActionMessage>);
 
   35namespace py = ::pybind11;
 
   39void EnsureMimetypeAssociations(SerializerRegistry* registry);
 
   41py::dict GetMimetypeToTypeDict(SerializerRegistry* registry);
 
   43py::dict GetTypeToMimetypeDict(SerializerRegistry* registry);
 
   45py::dict GetGlobalTypeToMimetype();
 
   47struct PySerializationArgs {
 
   49  std::string_view mimetype;
 
   53concept PyObjectEgltConvertsTo = 
requires(py::handle obj) {
 
   54  {EgltAssignInto(std::move(obj), std::declval<T*>())}
 
   55      ->std::same_as<absl::Status>;
 
   58using PyObjectToStdAnyCaster =
 
   59    std::function<absl::StatusOr<std::any>(py::handle)>;
 
   62PyObjectToStdAnyCaster MakeDefaultPyObjectToStdAnyCaster() {
 
   63  return [](py::handle obj) -> absl::StatusOr<std::any> {
 
   65      return absl::InvalidArgumentError(
 
   66          "Cannot convert None to a C++ type. Please provide a valid object.");
 
   70      auto pybind11_conversion = py::cast<T>(obj);
 
   71      return std::any(std::move(pybind11_conversion));
 
   72    } 
catch (
const py::cast_error& e) {
 
   73      return absl::InvalidArgumentError(absl::StrCat(
 
   74          "Failed to cast object to ", 
typeid(T).name(), 
": ", e.what()));
 
   80PyObjectToStdAnyCaster MakeDefaultPyObjectToStdAnyCaster()
 
   81    requires(PyObjectEgltConvertsTo<T>) {
 
   82  return [](py::handle obj) -> absl::StatusOr<std::any> {
 
   84      return absl::InvalidArgumentError(
 
   85          "Cannot convert None to a C++ type. Please provide a valid object.");
 
   88    auto act_provided_conversion = act::ConvertTo<T>(obj);
 
   89    if (act_provided_conversion.ok()) {
 
   90      return std::any(std::move(*act_provided_conversion));
 
   94      auto pybind11_conversion = py::cast<T>(std::move(obj));
 
   95      return std::any(std::move(pybind11_conversion));
 
   96    } 
catch (
const py::cast_error& e) {
 
   97      return absl::InvalidArgumentError(absl::StrCat(
 
   98          "Failed to cast object to ", 
typeid(T).name(), 
": ", e.what()));
 
  103absl::flat_hash_map<std::string, PyObjectToStdAnyCaster>&
 
  104GetCastersForMimetypes();
 
  106absl::StatusOr<std::any> CastPyObjectToAny(py::handle obj,
 
  107                                           std::string_view mimetype = 
"");
 
  109absl::Status EgltAssignInto(PySerializationArgs args, std::any* dest);
 
  115absl::Status EgltAssignInto(
const py::handle& obj, 
Chunk* chunk);
 
  119absl::Status EgltAssignInto(pybind11::handle obj, std::string* dest);
 
  122namespace act::pybindings {
 
  124absl::StatusOr<Chunk> PyToChunk(py::handle obj, std::string_view mimetype = 
"",
 
  125                                SerializerRegistry* registry = 
nullptr);
 
  127absl::StatusOr<py::object> PyFromChunk(
 
  128    Chunk chunk, std::string_view mimetype = 
"",
 
  129    const SerializerRegistry* registry = 
nullptr);
 
  131namespace py = pybind11;
 
  133void BindChunkMetadata(py::handle scope,
 
  134                       std::string_view name = 
"ChunkMetadata");
 
  136void BindChunk(py::handle scope, std::string_view name = 
"Chunk");
 
  138void BindNodeFragment(py::handle scope, std::string_view name = 
"NodeFragment");
 
  140void BindPort(py::handle scope, std::string_view name = 
"Port");
 
  142void BindActionMessage(py::handle scope,
 
  143                       std::string_view name = 
"ActionMessage");
 
  145void BindWireMessage(py::handle scope, std::string_view name = 
"WireMessage");
 
  147void BindSerializerRegistry(py::handle scope,
 
  148                            std::string_view name = 
"SerializerRegistry");
 
  150py::module_ MakeDataModule(py::module_ scope,
 
  151                           std::string_view module_name = 
"data");
 
ActionEngine data structures used to implement actions and nodes (data streams).