some docs
This commit is contained in:
parent
8f62f4d85f
commit
350808a8e2
18
R/function.R
18
R/function.R
@ -63,6 +63,14 @@ ts_result <- function(type, value) {
|
||||
#' @param result return type (ignored if overloads are provided)
|
||||
#' @export
|
||||
#' @md
|
||||
#'
|
||||
#' @return a ts function object which has a `call` method that will call the function with the given arguments, which will be checked for type correctness.
|
||||
#'
|
||||
#' @examples
|
||||
#' f <- ts_function(function(x = ts_integer(1), y = ts_character(1)) {
|
||||
#' x + nchar(y)
|
||||
#' }, result = ts_integer(1))
|
||||
#' f$call(1, "hello")
|
||||
ts_function <- function(f, ..., result = ts_void()) {
|
||||
args <- list(...)
|
||||
if (!is.null(result) && !is_ts_object(result)) {
|
||||
@ -117,9 +125,19 @@ print.ts_function <- function(x, ...) {
|
||||
#' Anything that is not a function simply returns itself.
|
||||
#' However, functions are wrapped with `Rserve::ocap()`,
|
||||
#' and the result is subsequently wrapped with `ts_app()`.
|
||||
#'
|
||||
#' @param x A ts function object (`ts_function()`)
|
||||
#' @export
|
||||
#' @md
|
||||
#'
|
||||
#' @returns An object of class 'OCref', see [Rserve::ocap()]
|
||||
#'
|
||||
#' @examples
|
||||
#' f <- ts_function(function(x = ts_integer(1), y = ts_character(1)) {
|
||||
#' x + nchar(y)
|
||||
#' }, result = ts_integer(1))
|
||||
#' app <- ts_app(f) # class of 'OCref'
|
||||
#' # this can now be used in an Rserve application, for example
|
||||
ts_app <- function(x) UseMethod("ts_app")
|
||||
|
||||
#' @export
|
||||
|
||||
51
R/types.R
51
R/types.R
@ -1,4 +1,4 @@
|
||||
#' Typed object
|
||||
#' Typed object (internal use only)
|
||||
#'
|
||||
#' This is the base type for all typed objects, and can be used to define
|
||||
#' custom types.
|
||||
@ -115,9 +115,11 @@ check_type.ts_function <- function(type, x) {
|
||||
#' Union type
|
||||
#'
|
||||
#' Create a union of types. Currently this only accepts schemas as strings.
|
||||
#' @param ... Types to merge
|
||||
#' @param ... Zod types to merge (as strings)
|
||||
#' @export
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_union("z.number()", "z.string()")
|
||||
ts_union <- function(...) sprintf("z.union([%s])", paste(..., sep = ", "))
|
||||
|
||||
ts_array <- function(type = c("z.number()", "z.boolean()", "z.string()")) {
|
||||
@ -157,6 +159,7 @@ n_type_fun <- function(n, type) {
|
||||
#' x$check(TRUE)
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # this will fail
|
||||
#' x$check(5)
|
||||
#' }
|
||||
ts_logical <- function(n = -1L) {
|
||||
@ -182,6 +185,14 @@ ts_logical <- function(n = -1L) {
|
||||
#' @return A ts object that accepts integer scalars or vectors of length `n`.
|
||||
#' @export
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_integer(1)
|
||||
#' x$check(1L)
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # this will fail
|
||||
#' x$check(1:10)
|
||||
#' }
|
||||
ts_integer <- function(n = -1L) {
|
||||
ts_object(
|
||||
n_type(n, "z.number()", "z.instanceof(Int32Array)"),
|
||||
@ -209,6 +220,15 @@ ts_integer <- function(n = -1L) {
|
||||
#' @return A ts object that accepts numeric scalars or vectors of length `n`.
|
||||
#' @export
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_numeric(1)
|
||||
#' x$check(1)
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # this will fail
|
||||
#' x$check(c(1, 2, 3))
|
||||
#' x$check("a")
|
||||
#' }
|
||||
ts_numeric <- function(n = -1L) {
|
||||
ts_object(
|
||||
n_type(n, "z.number()"),
|
||||
@ -231,6 +251,9 @@ ts_numeric <- function(n = -1L) {
|
||||
#' @return A ts object that accepts strings or string vectors of length `n`.
|
||||
#' @export
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_character(1)
|
||||
#' x$check("a")
|
||||
ts_character <- function(n = -1L) {
|
||||
ts_object(
|
||||
n_type(n, "z.string()"),
|
||||
@ -256,6 +279,15 @@ vector_as_ts_array <- function(x) {
|
||||
#'
|
||||
#' @export
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_factor(levels = c("a", "b"))
|
||||
#' x$check(factor("a", levels = c("a", "b")))
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # this will fail
|
||||
#' x$check("a")
|
||||
#' x$check(factor("c", levels = c("a", "b", "c")))
|
||||
#' }
|
||||
ts_factor <- function(levels = NULL) {
|
||||
ts_object(
|
||||
ifelse(is.null(levels),
|
||||
@ -290,6 +322,10 @@ ts_factor <- function(levels = NULL) {
|
||||
#'
|
||||
#' @export
|
||||
#' @md
|
||||
#'
|
||||
#' @examples
|
||||
#' x <- ts_list(a = ts_integer(1), b = ts_character(1))
|
||||
#' x$check(list(a = 1L, b = "a"))
|
||||
ts_list <- function(...) {
|
||||
values <- list(...)
|
||||
|
||||
@ -348,6 +384,10 @@ ts_list <- function(...) {
|
||||
#'
|
||||
#' @export
|
||||
#' @md
|
||||
#'
|
||||
#' @examples
|
||||
#' x <- ts_dataframe(a = ts_integer(1), b = ts_character(1))
|
||||
#' x$check(data.frame(a = 1L, b = "a"))
|
||||
ts_dataframe <- function(...) {
|
||||
values <- list(...)
|
||||
type <- "z.record(z.string(), z.any())"
|
||||
@ -379,11 +419,15 @@ ts_dataframe <- function(...) {
|
||||
|
||||
#' Null type
|
||||
#'
|
||||
#' This is a type that only accepts `NULL`.
|
||||
#' This is a type that only accepts `NULL`. For function return types, use `ts_void`.
|
||||
#'
|
||||
#' @return A ts object that only accepts `NULL`.
|
||||
#' @export
|
||||
#'
|
||||
#' @md
|
||||
#' @examples
|
||||
#' x <- ts_null()
|
||||
#' x$check(NULL)
|
||||
ts_null <- function() {
|
||||
ts_object(
|
||||
"z.null()",
|
||||
@ -402,6 +446,7 @@ ts_null <- function() {
|
||||
#' @return A ts object that accepts `NULL`.
|
||||
#' @export
|
||||
#' @md
|
||||
#' @seealso \code{\link{ts_null}}
|
||||
ts_void <- function() {
|
||||
ts_object(
|
||||
"z.void()",
|
||||
|
||||
@ -9,8 +9,18 @@ ts_app(x)
|
||||
\arguments{
|
||||
\item{x}{A ts function object (\code{ts_function()})}
|
||||
}
|
||||
\value{
|
||||
An object of class 'OCref', see \code{\link[Rserve:ocap]{Rserve::ocap()}}
|
||||
}
|
||||
\description{
|
||||
Anything that is not a function simply returns itself.
|
||||
However, functions are wrapped with \code{Rserve::ocap()},
|
||||
and the result is subsequently wrapped with \code{ts_app()}.
|
||||
}
|
||||
\examples{
|
||||
f <- ts_function(function(x = ts_integer(1), y = ts_character(1)) {
|
||||
x + nchar(y)
|
||||
}, result = ts_integer(1))
|
||||
app <- ts_app(f) # class of 'OCref'
|
||||
# this can now be used in an Rserve application, for example
|
||||
}
|
||||
|
||||
@ -16,3 +16,7 @@ A ts object that accepts strings or string vectors of length \code{n}.
|
||||
Strings are represented in Zod schema as either a string (\code{z.string()}),
|
||||
or a string array (\code{z.array(z.string())}).
|
||||
}
|
||||
\examples{
|
||||
x <- ts_character(1)
|
||||
x$check("a")
|
||||
}
|
||||
|
||||
@ -15,3 +15,7 @@ A ts object that accepts data frames with the specified types.
|
||||
\description{
|
||||
This is essentially a list, but the elements must have names and are all the same length.
|
||||
}
|
||||
\examples{
|
||||
x <- ts_dataframe(a = ts_integer(1), b = ts_character(1))
|
||||
x$check(data.frame(a = 1L, b = "a"))
|
||||
}
|
||||
|
||||
@ -15,3 +15,13 @@ A ts object that accepts factors with the specified levels.
|
||||
\description{
|
||||
Factors are integers with labels. On the JS side, these are \emph{always} represented as a string array (even if only one value - yay!).
|
||||
}
|
||||
\examples{
|
||||
x <- ts_factor(levels = c("a", "b"))
|
||||
x$check(factor("a", levels = c("a", "b")))
|
||||
|
||||
\dontrun{
|
||||
# this will fail
|
||||
x$check("a")
|
||||
x$check(factor("c", levels = c("a", "b", "c")))
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,3 +29,9 @@ can explicitly be defined with their types as formal arguments:
|
||||
\if{html}{\out{<div class="sourceCode">}}\preformatted{ts_function(function(x = ts_integer(), y = ts_string()) \{ ... \})
|
||||
}\if{html}{\out{</div>}}
|
||||
}
|
||||
\examples{
|
||||
f <- ts_function(function(x = ts_integer(1), y = ts_character(1)) {
|
||||
x + nchar(y)
|
||||
}, result = ts_integer(1))
|
||||
f$call(1, "hello")
|
||||
}
|
||||
|
||||
@ -16,3 +16,12 @@ A ts object that accepts integer scalars or vectors of length \code{n}.
|
||||
Integers are represented in Zod schema as either a number (\code{z.number()}),
|
||||
or a Int32Array (\code{z.instanceof(Int32Array)}).
|
||||
}
|
||||
\examples{
|
||||
x <- ts_integer(1)
|
||||
x$check(1L)
|
||||
|
||||
\dontrun{
|
||||
# this will fail
|
||||
x$check(1:10)
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,3 +15,7 @@ A ts object that accepts lists with the specified types.
|
||||
\description{
|
||||
A list is a vector of other robjects, which may or may not be named.
|
||||
}
|
||||
\examples{
|
||||
x <- ts_list(a = ts_integer(1), b = ts_character(1))
|
||||
x$check(list(a = 1L, b = "a"))
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ x <- ts_logical(1)
|
||||
x$check(TRUE)
|
||||
|
||||
\dontrun{
|
||||
# this will fail
|
||||
x$check(5)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,5 +10,9 @@ ts_null()
|
||||
A ts object that only accepts \code{NULL}.
|
||||
}
|
||||
\description{
|
||||
This is a type that only accepts \code{NULL}.
|
||||
This is a type that only accepts \code{NULL}. For function return types, use \code{ts_void}.
|
||||
}
|
||||
\examples{
|
||||
x <- ts_null()
|
||||
x$check(NULL)
|
||||
}
|
||||
|
||||
@ -16,3 +16,13 @@ A ts object that accepts numeric scalars or vectors of length \code{n}.
|
||||
Numbers are represented in Zod schema as either a number (\code{z.number()}),
|
||||
or a Float64Array (\code{z.instanceof(Float64Array)}).
|
||||
}
|
||||
\examples{
|
||||
x <- ts_numeric(1)
|
||||
x$check(1)
|
||||
|
||||
\dontrun{
|
||||
# this will fail
|
||||
x$check(c(1, 2, 3))
|
||||
x$check("a")
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\alias{is_ts_object}
|
||||
\alias{get_type}
|
||||
\alias{check_type}
|
||||
\title{Typed object}
|
||||
\title{Typed object (internal use only)}
|
||||
\usage{
|
||||
ts_object(
|
||||
input_type = "any",
|
||||
|
||||
@ -7,8 +7,11 @@
|
||||
ts_union(...)
|
||||
}
|
||||
\arguments{
|
||||
\item{...}{Types to merge}
|
||||
\item{...}{Zod types to merge (as strings)}
|
||||
}
|
||||
\description{
|
||||
Create a union of types. Currently this only accepts schemas as strings.
|
||||
}
|
||||
\examples{
|
||||
x <- ts_union("z.number()", "z.string()")
|
||||
}
|
||||
|
||||
@ -13,3 +13,6 @@ A ts object that accepts \code{NULL}.
|
||||
This is a type that accepts null values (this would typically be used for
|
||||
functions that return nothing).
|
||||
}
|
||||
\seealso{
|
||||
\code{\link{ts_null}}
|
||||
}
|
||||
|
||||
30
tests/testthat/test-custom-types.R
Normal file
30
tests/testthat/test-custom-types.R
Normal file
@ -0,0 +1,30 @@
|
||||
hist_type <- ts_object(
|
||||
input_type = "z.object({
|
||||
breaks: z.array(z.number()),
|
||||
counts: z.array(z.number()),
|
||||
density: z.array(z.number()),
|
||||
mids: z.array(z.number()),
|
||||
xname: z.string(),
|
||||
equidist: z.boolean(),
|
||||
})",
|
||||
return_type = "Robj.list({
|
||||
breaks: Robj.numeric(),
|
||||
counts: Robj.numeric(),
|
||||
density: Robj.numeric(),
|
||||
mids: Robj.numeric(),
|
||||
xname: Robj.character(1),
|
||||
equidist: Robj.logical(1),
|
||||
})",
|
||||
check = function(x) {
|
||||
stopifnot(is.list(x))
|
||||
stopifnot(all(c("breaks", "counts", "density", "mids", "xname", "equidist") %in% names(x)))
|
||||
stopifnot(is.numeric(x$breaks))
|
||||
stopifnot(is.numeric(x$counts))
|
||||
stopifnot(is.numeric(x$density))
|
||||
stopifnot(is.numeric(x$mids))
|
||||
stopifnot(is.character(x$xname))
|
||||
stopifnot(is.logical(x$equidist))
|
||||
stopifnot(isTRUE(all.equal(length(x$breaks), length(x$counts), length(x$density), length(x$mids))))
|
||||
x
|
||||
}
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user