jonthegeek / rapid

R 'API' documents
https://rapid.api2r.org/
Other
6 stars 1 forks source link

Refactor spike: parallel_table (?) data structure? #50

Open jonthegeek opened 1 year ago

jonthegeek commented 1 year ago

I have several things that use validate_parallel() to make sure things are compatible with a key property. I think it might make sense to make this a parent class with that validator built in, with properties specifying which field is the key, which are required, and which are optional (presumably with specifications for required and optional that don't have to be parallel, but confirm that those cases are used in ways that make sense).

In the child objects, we'd want to define those key/required/optional fields in a non-updatable way.

This mostly works. The only issue really is that prints should hide the things users can't mess with (and/or explain them):

devtools::load_all()

parallel_table <- S7::new_class(
  "parallel_table",
  properties = list(
    .key = character_scalar_property("key"),
    .required = class_character | NULL,
    .optional = class_character | NULL
  ),
  abstract = TRUE,
  validator = function(self) {
    validate_parallel(
      obj = self,
      key_name = self@.key,
      required = self@.required, 
      optional = self@.optional
    )
  }
)

constant_property <- function(x_value) {
  force(x_value)
  S7::new_property(
    class = class_character,
    getter = function(self) {
      x_value
    }
  )
}

example_parallel <- S7::new_class(
  name = "example_parallel",
  parent = parallel_table,
  properties = list(
    name = class_character | NULL,
    age = S7::class_integer | NULL,
    favorite_color = class_character | NULL,
    .key = constant_property("name"),
    .required = constant_property("age"),
    .optional = constant_property("favorite_color")
  )
)

example_parallel()
john_person <- example_parallel(name = "John", age = 1L)
john_person
example_parallel(name = "John", age = 1:3)
john_person@.key <- "age"
example_parallel@constructor