diff --git a/DESCRIPTION b/DESCRIPTION index 60182650..d51c8f7f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -48,6 +48,7 @@ Collate: 'calculate_hash.R' 'capitalize.R' 'catn.R' + 'check_operators.R' 'check_packages_installed.R' 'chunk.R' 'compose.R' diff --git a/NAMESPACE b/NAMESPACE index e45538e2..6b52b5ec 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -37,6 +37,8 @@ S3method(remove_named,default) S3method(remove_named,environment) S3method(strip_srcrefs,"function") S3method(strip_srcrefs,default) +export("%check&&%") +export("%check||%") export("%nin%") export("get_private<-") export(Callback) diff --git a/NEWS.md b/NEWS.md index 1b87ee8d..61e1685f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # mlr3misc (development version) * feat: `as_callbacks()` returns a list named by the callback ids now. +* feat: Added logical operators `%check&&%` and `%check||%` for `check_*`-functions from `checkmate` (moved here from `mlr3pipelines`). # mlr3misc 0.16.0 diff --git a/R/check_operators.R b/R/check_operators.R new file mode 100644 index 00000000..4bee28d5 --- /dev/null +++ b/R/check_operators.R @@ -0,0 +1,35 @@ +#' @title Logical Check Operators +#' +#' @description +#' Logical AND and OR operators for `check_*`-functions from [`checkmate`][`checkmate::checkmate`]. +#' +#' @param lhs,rhs (`function()`)\cr +#' `check_*`-functions that return either `TRUE` or an error message as a `character(1)`. +#' +#' @return Either `TRUE` or a `character(1)`. +#' +#' @name check_operators +#' @examples +#' library(checkmate) +#' +#' x = c(0, 1, 2, 3) +#' check_numeric(x) %check&&% check_names(names(x), "unnamed") # is TRUE +#' check_numeric(x) %check&&% check_true(all(x < 0)) # fails +#' +#' check_numeric(x) %check||% check_character(x) # is TRUE +#' check_number(x) %check||% check_flag(x) # fails +NULL + +#' @export +#' @rdname check_operators +`%check&&%` = function(lhs, rhs) { + if (!isTRUE(lhs) && !isTRUE(rhs)) return(paste0(lhs, ", and ", rhs)) + if (isTRUE(lhs)) rhs else lhs +} + +#' @export +#' @rdname check_operators +`%check||%` = function(lhs, rhs) { + if (!isTRUE(lhs) && !isTRUE(rhs)) return(paste0(lhs, ", or ", rhs)) + TRUE +} diff --git a/man/check_operators.Rd b/man/check_operators.Rd new file mode 100644 index 00000000..17829969 --- /dev/null +++ b/man/check_operators.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/check_operators.R +\name{check_operators} +\alias{check_operators} +\alias{\%check&&\%} +\alias{\%check||\%} +\title{Logical Check Operators} +\usage{ +lhs \%check&&\% rhs + +lhs \%check||\% rhs +} +\arguments{ +\item{lhs, rhs}{(\verb{function()})\cr +\verb{check_*}-functions that return either \code{TRUE} or an error message as a \code{character(1)}.} +} +\value{ +Either \code{TRUE} or a \code{character(1)}. +} +\description{ +Logical AND and OR operators for \verb{check_*}-functions from \code{\link[checkmate:checkmate-package]{checkmate}}. +} +\examples{ +library(checkmate) + +x = c(0, 1, 2, 3) +check_numeric(x) \%check&&\% check_names(names(x), "unnamed") # is TRUE +check_numeric(x) \%check&&\% check_true(all(x < 0)) # fails + +check_numeric(x) \%check||\% check_character(x) # is TRUE +check_number(x) \%check||\% check_flag(x) # fails +} diff --git a/tests/testthat/test_check_operators.R b/tests/testthat/test_check_operators.R new file mode 100644 index 00000000..295e5db7 --- /dev/null +++ b/tests/testthat/test_check_operators.R @@ -0,0 +1,13 @@ +test_that("check operators", { + # AND operator + expect_true(TRUE %check&&% TRUE) + expect_equal(TRUE %check&&% "error", "error") + expect_equal("error" %check&&% TRUE, "error") + expect_equal("error1" %check&&% "error2", "error1, and error2") + + # OR operator + expect_true(TRUE %check||% TRUE) + expect_true(TRUE %check||% "error") + expect_true("error" %check||% TRUE) + expect_equal("error1" %check||% "error2", "error1, or error2") +})