Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to do typechecking and conversion on the values of key-value options #1032

Merged
merged 4 commits into from
Feb 1, 2024

Conversation

dpvc
Copy link
Member

@dpvc dpvc commented Dec 11, 2023

This PR adds optional type checking and conversion to the keyvalueOptions() function. Currently, the allowed argument gives an object that says what keys are allowed (ones with non-zero values in that object). Here, we extend the use of the allowed object to provide data for type checking and converting the values of the given keys.

This is done through a new KeyValueType object that has validate() and convert() methods (and a name, for potential error reporting). There is a KeyValueTypeDefinition() function that makes creating these objects easier, and a KeyValueTypes object that holds predefined definitions for the standard types (boolean, number, string) and some variations (integer, dimen, and oneof() that gives a collection of valid option for the string). These seem to be a good base set of definitions, but you can create your own custom types with more detailed checker and converter, as needed.

We aren't currently using this feature now, but it would be useful in the siunitx extension that I am reviewing for PCC now.

A similar idea may also be useful for making the option checking more robust in the future (in util/Options.ts), where we only do key name checking, but not type checking currently.

@dpvc dpvc requested a review from zorkow December 11, 2023 16:00
@dpvc dpvc added this to the v4.0 milestone Dec 11, 2023
Base automatically changed from fix-keyvalue to develop December 20, 2023 22:08
Copy link
Member

@zorkow zorkow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not be much simpler to make the KeyValueType<T> a class and then create objects with new instead of using KeyValueTypeDefinition?

@dpvc
Copy link
Member Author

dpvc commented Dec 28, 2023

You don't need new instances each time they are used. The definitions are the same, so only one object needs to be used for each type. (Except the oneof, where you have to specify the strings that are valid.) Also, since the verify and convert methods differently by the type of T, you would either have to have a bunch of different subclasses, one for each T, or have the verify and convert functions have a switch on the type of T (which I'm not sure can be done with a template type).

If you have something else in mind, can you be more explicit about it?

@zorkow
Copy link
Member

zorkow commented Jan 18, 2024

I did not mean to create a new object in every call. I was more thinking about having a single class instead of a type and definition function, i.e., something along the line of:

export class KeyValueType<T> {

  constructor(
    public name: string,
    public verify: (value: string) => boolean,
    public convert: (value: string) => T
  ) {}

}

and then rewriting the KeyValueTypes constant to:

export const KeyValueTypes: {[name: string]: KeyValueType<any> | ((data: any) => KeyValueType<any>)} = {
  boolean: new KeyValueType<boolean>(
    'boolean',
    (value) => value === 'true' || value === 'false',
    (value) => value === 'true'
  ),
...

This way we still only create one instance object for each entry. But we save the Definition method.

@dpvc
Copy link
Member Author

dpvc commented Jan 19, 2024

OK, I made the changes from the object to a class. That is a good change, thanks. Please take a look.

@dpvc dpvc requested a review from zorkow January 19, 2024 00:40
Copy link
Member

@zorkow zorkow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm.

@dpvc dpvc merged commit 7a3fd3e into develop Feb 1, 2024
@dpvc dpvc deleted the keyvalue-typechecking branch February 1, 2024 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants