Skip to content

Commit

Permalink
Implement api_info() as S7 (#21)
Browse files Browse the repository at this point in the history
* Mostly working S7 implementation of a basic pair of classes.

Still a lot to do before I like it, but it's promising!

* Implement info as S7.

Closes #3.
  • Loading branch information
jonthegeek authored Aug 27, 2023
1 parent 36586b8 commit 1eee33e
Show file tree
Hide file tree
Showing 26 changed files with 413 additions and 444 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ URL: https://jonthegeek.github.io/rapid/,
BugReports: https://github.com/jonthegeek/rapid/issues
Imports:
rlang (>= 1.1.0),
S7,
stbl
Suggests:
testthat (>= 3.0.0)
Expand Down
3 changes: 1 addition & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# Generated by roxygen2: do not edit by hand

S3method(.add_class,default)
S3method(.add_class,list)
export(api_contact)
export(api_info)
export(api_license)
importFrom(rlang,check_dots_empty)
importFrom(rlang,check_dots_used)
Expand Down
27 changes: 27 additions & 0 deletions R/00-properties.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# These should probably be defined in a separate package.

character_scalar_property <- function(x_arg, regex = NULL) {
S7::new_property(
class = S7::class_character,
setter = function(self, value) {
# TODO: Watch S7 dev to see if this can be less hacky.
call <- rlang::caller_env(3)
value <- stbl::stabilize_chr_scalar(
value,
allow_null = FALSE,
regex = regex,
x_arg = x_arg,
call = call
)
S7::prop(self, x_arg, check = FALSE) <- value
self
}
)
}

url_scalar_property <- function(x_arg) {
character_scalar_property(
x_arg,
regex = "http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\(\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+"
)
}
32 changes: 32 additions & 0 deletions R/01-info_contact.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#' Contact information for the API
#'
#' Validate the contact information for an API.
#'
#' @param name The identifying name of the contact person/organization.
#' @param url The URL pointing to the contact information. This *must* be in the
#' form of a URL.
#' @param email The email address of the contact person/organization. This
#' *must* be in the form of an email address.
#'
#' @return An `api_contact` S7 object, with fields `name`, `email`, and
#' `url`.
#' @export
#'
#' @examples
#' api_contact(
#' "API Support",
#' "support@example.com",
#' "https://www.example.com/support"
#' )
api_contact <- S7::new_class(
"api_contact",
package = "rapid",
properties = list(
name = character_scalar_property("name"),
email = character_scalar_property(
"email",
regex = "^[^@]+@[^@]+$"
),
url = url_scalar_property("url")
)
)
49 changes: 49 additions & 0 deletions R/01-info_license.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Anything at 01 can only have dependencies at 00.

#' License information for the API
#'
#' Validate the license information for an API.
#'
#' @inheritParams rlang::args_dots_empty
#' @param name The license name used for the API.
#' @param identifier An
#' [SPDX](https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60)
#' license expression for the API. The `identifier` field is mutually
#' exclusive of the `url` field.
#' @param url A URL to the license used for the API. This *must* be in the form
#' of a URL. The `url` field is mutually exclusive of the `identifier` field.
#'
#' @return An `api_license` S7 object, with fields `name`, `identifier`, and
#' `url`.
#' @export
#'
#' @examples
#' api_license(
#' "Apache 2.0",
#' identifier = "Apache-2.0"
#' )
#' api_license(
#' "Apache 2.0",
#' url = "https://opensource.org/license/apache-2-0/"
#' )
api_license <- S7::new_class(
"api_license",
package = "rapid",
properties = list(
name = character_scalar_property("name"),
identifier = character_scalar_property("identifier"),
url = url_scalar_property("url")
),
constructor = function(name = character(),
...,
identifier = character(),
url = character()) {
rlang::check_dots_empty()
S7::new_object(NULL, name = name, identifier = identifier, url = url)
},
validator = function(self) {
if (length(self@identifier) && length(self@url)) {
"At most one of @identifier and @url must be supplied."
}
}
)
47 changes: 47 additions & 0 deletions R/02-info.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#' Information about the API
#'
#' The object provides metadata about the API. The metadata *may* be used by the
#' clients if needed, and *may* be presented in editing or documentation
#' generation tools for convenience.
#'
#' @param contact The contact information for the exposed API, generated via
#' [api_contact()].
#' @param description A description of the API. [CommonMark
#' syntax](https://spec.commonmark.org/) *may* be used for rich text
#' representation.
#' @param license The license information for the exposed API, generated via
#' [api_license()].
#' @param summary A short summary of the API.
#' @param terms_of_service A URL to the Terms of Service for the API. This
#' *must* be in the form of a URL when provided.
#' @param title The title of the API.
#' @param version The version of the API document (which is distinct from the
#' OpenAPI Specification version or the API implementation version).
#'
#' @return An `api_info` S7 object.
#' @export
#' @examples
#' api_info()
#' api_info(
#' title = "My Cool API",
#' license = api_license(
#' name = "Apache 2.0",
#' url = "https://opensource.org/license/apache-2-0/"
#' )
#' )
api_info <- S7::new_class(
"api_info",
package = "rapid",
# Design choice: These are strictly alphabetized, since we allow any to be
# empty. May later want to order them to match the validated version, where
# required parameters will come first (before ... during construction).
properties = list(
contact = api_contact,
description = character_scalar_property("description"),
license = api_license,
summary = character_scalar_property("summary"),
terms_of_service = url_scalar_property("terms_of_service"),
title = character_scalar_property("title"),
version = character_scalar_property("version")
)
)
54 changes: 0 additions & 54 deletions R/info-contact.R

This file was deleted.

57 changes: 0 additions & 57 deletions R/info-license.R

This file was deleted.

53 changes: 0 additions & 53 deletions R/info.R

This file was deleted.

13 changes: 0 additions & 13 deletions R/oas.R

This file was deleted.

15 changes: 0 additions & 15 deletions R/objects.R

This file was deleted.

23 changes: 0 additions & 23 deletions R/rapid.R

This file was deleted.

Loading

0 comments on commit 1eee33e

Please sign in to comment.