Skip to main content

WRAPPER_RAISE_CONDITION_HELPER_FN

Constant WRAPPER_RAISE_CONDITION_HELPER_FN 

Source
const WRAPPER_RAISE_CONDITION_HELPER_FN: &str = "function(.val, .call_default) {\n  # The condition object for one tagged value `.v`.\n  .cond <- function(.v) {\n    .msg <- .v$error\n    # `.v$call` is the call the Rust side captured, NULL to use the wrapper\'s\n    # call, or FALSE for a condition raised without one (`call = none`, R\'s\n    # `call. = FALSE`), which is signalled with `call = NULL`.\n    .call <- if (isFALSE(.v$call)) NULL else if (is.null(.v$call)) .call_default else .v$call\n    # A generated S3 method passes its frame instead of a call, so that the\n    # generic\'s call (`summary(x)` for `summary.cls(x)`, the assignment for a\n    # replacement method) is built only now, when a condition is raised. The\n    # resolver recovers the generic\'s call from that method frame.\n    if (is.environment(.call)) .call <- .miniextendr_frame_call(.call)\n    .class <- .v$class\n    # `arg_error!` writes the class \".miniextendr_conversion_error_class\"\n    # where the crate\'s `conversion_error_class` belongs: only the generated R\n    # knows those classes, bound under that name at the end of the wrappers\n    # preamble, so they replace it here. The copy of this helper that signals\n    # deferred conditions lives in the base namespace, where the name is\n    # unbound and the marker is dropped.\n    .at <- match(\".miniextendr_conversion_error_class\", .class)\n    if (!is.na(.at)) {\n      .class <- append(.class[-.at], get0(\".miniextendr_conversion_error_class\", ifnotfound = NULL), after = .at - 1L)\n    }\n    # `.v$data` is an optional named list of structured fields (from the\n    # macros\' `data = ...` form). When present, splice its named elements into\n    # the condition object alongside message/call/kind so handlers can read\n    # `e$<name>`. `utils::modifyList` keeps the base fields and appends the\n    # data fields; a malformed (non-list / unnamed) payload is ignored.\n    # `keep.null = TRUE`: a field the Rust side set to `RValue::Null` is a\n    # present field whose value is NULL, and must stay in `names(e)`; the\n    # default would silently drop it (found downstream via a\n    # `RConditionData::data()` returning an explicit NULL entry).\n    .data <- .v$data\n    # A cause the Rust side attached (`RCondition::with_parent`) travels as\n    # the tagged value `.mx_parent` and becomes the condition object\n    # `e$parent`, as `rlang::abort(parent = )` chains conditions. It is not\n    # signalled, and its classes stay out of this condition\'s.\n    if (is.list(.data) && !is.null(.data[[\".mx_parent\", exact = TRUE]])) {\n      .parent <- .cond(.data[[\".mx_parent\", exact = TRUE]])\n      .data[[\".mx_parent\"]] <- NULL\n      .data[[\"parent\"]] <- .parent\n    }\n    .cond_fields <- function(base) {\n      if (is.null(.data) || !is.list(.data) || is.null(names(.data))) {\n        base\n      } else {\n        utils::modifyList(base, .data, keep.null = TRUE)\n      }\n    }\n    switch(.v$kind,\n      warning = structure(.cond_fields(list(message = .msg, call = .call, kind = \"warning\")),\n        class = c(.class, \"rust_warning\", \"simpleWarning\", \"warning\", \"condition\")),\n      message = structure(.cond_fields(list(message = paste0(.msg, \"\\n\"), call = NULL, kind = \"message\")),\n        class = c(.class, \"rust_message\", \"simpleMessage\", \"message\", \"condition\")),\n      condition = structure(.cond_fields(list(message = .msg, call = .call, kind = \"condition\")),\n        class = c(.class, \"rust_condition\", \"simpleCondition\", \"condition\")),\n      panic = structure(list(message = .msg, call = .call, kind = \"panic\"),\n        class = c(\"rust_error\", \"simpleError\", \"error\", \"condition\")),\n      # error / result_err / none_err / conversion / other: an error whose class\n      # vector and data (if any) come from the Rust side, e.g. a\n      # `Result<T, E: RConditionData>`.\n      structure(.cond_fields(list(message = .msg, call = .call, kind = .v$kind)),\n        class = c(.class, \"rust_error\", \"simpleError\", \"error\", \"condition\")))\n  }\n  .c <- .cond(.val)\n  switch(.val$kind,\n    warning = warning(.c),\n    message = message(.c),\n    condition = signalCondition(.c),\n    stop(.c)\n  )\n  invisible(NULL)\n}";
Expand description

The package preamble already binds the resolver; reuse it there.