some docs

This commit is contained in:
Tom Elliott 2025-02-24 14:35:02 +13:00
parent 8f62f4d85f
commit 350808a8e2
16 changed files with 167 additions and 6 deletions

View File

@ -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

View File

@ -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()",

View File

@ -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
}

View File

@ -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")
}

View File

@ -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"))
}

View File

@ -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")))
}
}

View File

@ -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")
}

View File

@ -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)
}
}

View File

@ -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"))
}

View File

@ -21,6 +21,7 @@ x <- ts_logical(1)
x$check(TRUE)
\dontrun{
# this will fail
x$check(5)
}
}

View File

@ -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)
}

View File

@ -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")
}
}

View File

@ -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",

View File

@ -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()")
}

View File

@ -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}}
}

View 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
}
)