捕获 `{cli}` 输出以进行报告

Capture `{cli}` output for reporting

我想捕获 {cli} 产生的动态输出以在错误 reporting/logging 中使用。

这是一个例子:

my_function <- function(val, return_message = TRUE) {
  
  if(val == 'a'){
    if (return_message) cli::cli_alert("your value {val} = a!")
  } else {
    if (return_message) cli::cli_alert("your value {val} is not equal to a!")
  }
  
  if (return_message) cli::cli_h2("processing now complete")
  
  return(val)
  
}

使用 my_function,它 returns val 并根据输入值打印一条动态消息:

→ your value x is not equal to a!

── processing now complete ──

[1] "x"

有没有什么方法可以捕获 {cli} 函数的动态输出,最好是附加到列表或类似的方法?

理想的输出应该是这样的:

my_data <- list(val = "x", message = c("your value x is not equal to a!", "processing now complete"))

我不认为 cli_X() returns 文本,但您可以想象一个包装器可以做您想要的事情。以此作为开始:

cli_wrapper <- function(str, type="alert", return_str = TRUE, return_message=TRUE, ...){
  str <- with(list(...), glue::glue(str))
  if(return_message){
    cmd <- glue::glue('cli::cli_{type}("{str}")')
    eval(parse(text=cmd))
  }
  if(return_str){
    invisible(str)  
  }
}

在上面的函数中,return_message表示cli_X()函数是否应该运行,return_str表示是否应该返回字符串(不可见)。然后您可以使用 cli_wrapper() 函数重写您的函数:

my_function <- function(val, return_message = TRUE) {
  message <- NULL  
  if(val == 'a'){
    message <- c(message, cli_wrapper("your value {val} = a!", type="alert", val = val, return_message = return_messasge))
  }else{
    message <- c(message, cli_wrapper("your value {val} is not equal to a!", type="alert", val = val, return_message = return_messasge))
  }
  message <- c(message, cli_wrapper("processing now complete", type="h2", return_message = return_messasge))
  ret <- list(val=val, message = message)
  invisible(ret)
}

运行 函数以几种不同的方式给出以下输出:

my_data <- my_function(val="x", return_message=TRUE)
# → your value x is not equal to a!
#   
#   ── processing now complete ──
# 

my_data
# $val
# [1] "x"
# 
# $message
# [1] "your value x is not equal to a!" "processing now complete"        
# 

my_data <- my_function(val="x", return_message=FALSE)

my_data
# $val
# [1] "x"
# 
# $message
# [1] "your value x is not equal to a!" "processing now complete"