With recent YAML
inputs we opened up a Pandora's box. Instead of doing slight redesign of input specifications, a need for rewrite of input specifications emerged. Rationale: we're doing this to make inputs feel more native to R, hence other users, hence make rapport
more cooler, etc.
While I was implementing integer
inputs, it came to me that there's no need for yet another input type, but we can pass something like integer: TRUE
to existing number
input. A plea for option
input to accept multiple values was also a game changer. Then why not making multiple
available for all standalone inputs? When it comes to string
inputs - why not performing more checks in there, like nchar
or regexp
validation, etc. That said, let's unlock this further.
As I like renaming stuff, this is a perfect opportunity to do it (again) 👍 , like changing mandatory
attribute to required
, or changing default
to value
. Backward compatibility is a must. Reason: they seem more intuitive. mandatory
was my "invention" and it sucks.
Key changes:
- drop
type
attribute and/or perform checks based on native R object attributes, like class
(or storage.mode
, and the likes)
- provide more class-specific checks, like
nchar
for strings or integer
for numbers
- use method dispatching to perform input validations (write bunch of validators for custom classes)
- use YAML as an intermediary format (d'uh) to facilitate parsing/deparsing + making it more rea
Dataset inputs
We have them for a good reason. I guess that inputs should have one additional attribute like: standalone
(I don't like it, doesn't sound native enough). Currently rapport
accepts only data.frame
objects, but when I think about #41 , it makes me wonder if we can expand the data
argument a bit. What if we can pass all kinds of objects in there, and match inputs more dynamically. Imagine this: you pass a list
or other recursive
object, and match its named attributes with the provided inputs.
Standalone inputs
string
Dilemma: how to perform nchar
checks? Should we provide only one number, or a vector to perform vectorised nchar
check? What about limit
s? Should we drop 'em, and replace with length
. In that case, I guess that length
will take over min
and max
attributes, as it feels more native.
- name: s
class: character
label: String input
description: Bla bla string string
required: TRUE
value:
- fee
- fi
- foo
- fam
nchar: 10
length:
min: 1
max: 100
regexp: "^.+$"
number
Of course, length
can take min
and max
, but I'll omit it here. Notice the change from number
to numeric
Q: should we add class: integer
or provide separate argument to bypass precision issue (in case you want round numbers larger than .Machine$integer.max + 1
). Or to check via storage.mode
, or dunno what.
- name: n
class: numeric
label: Number input
description: Bla bla numeric numeric
required: FALSE
value: 10
length: 1
boolean
Yes, length
can be different, as well as value
. Should we check anything other than that? I mean... what's specific to NA
and useful at the same time, so that it's worth implementing?
- name: b
class: logical
label: Logical input
description: Bla bla logical logical
required: TRUE
value: TRUE
length: 1
option
Okay, how should we make this native? My guess is either to provide a custom object (new class
), or to provide an additional argument that will allow matchng like match.arg
or something else.
Stuff to think about
I'll just brainstorm in here:
- how to handle
NA
and should we do that at all?
names
attribute: this should be handy in, say populating select boxes in HTML form (label: value)
- custom validations: write custom methods or pass a handler that will check given attribute