-
Notifications
You must be signed in to change notification settings - Fork 870
Description
I've been following toml for a while and noticed that many features get heavily debated (relatively speaking) or even outright rejected for an assortment of reasons. Generally speaking, it's because the feature or proposal, while a nice addition, is either not necessary (and therefore would ruin the simplistic nature of toml) or is too ambiguous (and would therefore confuse users if they don't know a new syntax/feature has been implemented and its quirks) - sometimes both. While I agree with the reasoning for rejections and see the merit in keeping toml relatively simple, I also would like to see these features optionally implemented.
Thus, I think it would be best if toml had an extension system, whose naming and overall functionality would be similar to that of XMPP - another open and RFC standard. Essentially, features that may not be suitable for the base toml standard itself can instead be amended as an extension with a specific "ID", such as TLX-YYY
(where YYY is the number of the extension). Users can then specify these extensions in their toml files if they want to use the features in that extension. Parsers would then optionally implement extensions that become a part of toml
For simplicity and as an example, let's assume this gets implemented as part of the toml 1.1.0 standard. I will also use the term "parser" generally, but I'm mostly referring to implementations. Which extensions 1.1 compliant parsers actually implement is up to the developer of said parser, since extensions are optional. However, in order for parsers to be 1.1 complant, they should list what extensions they support (much like how toml parsers say what version of toml they are compliant to in their readme), and throw an error if the user indicates they want to use an extension that the parser does not support. An error should also be thrown if a user is using a feature that is part of an extension but did not specify in their file that they are using that extension; This way, there will be no ambiguity and users will be clearly told what is going on in terms of the extension system.
Users would indicate what extensions they want to use in the file itself, like so:
[toml]
extensions = [1, 3, 4, 7]
A 1.1 compliant parser would read this, and either accept it, or throw an error like my-example-parser does not support TLX-003
if it did not support (i.e. the authors did not implement) TLX-003
. Similarly, the parser should throw an error if it reads a feature that it supports but the extension for that feature has not been specified; For example, if Filesizes are part of TLX-003
, and a user tries to use filesizes in their toml file without specifying extensions = [3]
, the parser should throw an error like File sizes requires extension TLX-003
or File sizes are not part of the 1.1 toml specification; You must specify TLX-003
. This system prevents parser developers from being forced to implement all these features, and also prevents users from being forced to use these features when they didn't specify that they wanted to.
The reason specifying an error is important is that 1.0 and below compliant parsers would just read the extensions
field as a normal variable, so it's important that 1.1 and above compliant parsers don't have the same behavior for ambiguity reasons. For similar reasons.1.1 compliant parsers should also specify when they correctly read an extension, e.g. TLX-001 in use
.
Additionally, with this syntax, adding a field specifying the version of toml used in the file (mentioned many, many times; #860 highlights them all) and specifying a toml schema (#792) could be naturally implemented:
[toml]
version = { major = 1, minor = 1, rev = 0 }
schema = "<url>"
extensions = [1, 3, 4, 7]
Specifying a toml version is a good idea in general so that parsers can know if the user is using a standard that the parser does not support. It would be an even better idea now in the context of the extension system: When a version is not specified, 1.1 compliant parsers can assume a version of the toml standard is being used that does not support extensions, and thus immediately reject the file if that's the case (since in our example there are no extensions before 1.1). They could also maybe assume that a toml file with no [toml]
table specified at all is instead using version 1.0 of the standard, since, in this example, that's the latest version that does not implement having a version field in the toml file.
To better demonstrate how this system and how it could eliminate ambiguity and unnecessary complexity while still allowing users to use new features, here are some issues/prs (and example extension names) that are a great example or fit for this system:
- TLX-001: Include Files (I think TOML should support file inclusion… #81)
- TLX-002: Duration (Feature request: Add a duration/timedelta type #514/Proposal to add a duration type #717)
- TLX-003: Hex Floats (Add syntax for hexadecimal floating point values #562)
- TLX-004: User-defined Values (Optionally supported implementation-defined values #707)
- TLX-005: Filesizes (Add nicer syntax for file sizes #912)
Many of these are in the "need to be decided" category for 1.1.0 (as seen in #928) for one reason another. With this system, there would be no need to decide: any proposals that may be problematic and need a tough decision can simply just be implemented as an extension instead.
This system may seem to be the same as #707, but there are a few key differences. This system overall is much simplier (users just need to enter what extensions they're using in an array) and actually standardized (since the maintainers of toml define the extensions and parsers implement it). With #707, more commonly used features would have to be replicated by each user many times. For example, if many users wanted to use filesizes in their toml files, each user would have to make their own complex defition for filesizes. However, with this system, they would just instead just add '5' to their extensions field. This system doesn't also necessarily replace #707; Users can still implement their own types for really out of scope or extremely customizes types that are even beyond the scope of an extension and are unlikely to be used by others. This is why I listed User-defined types as an extension above. Obviously, the quirks of this system need to be discussed, but I think that if this system is implemented, it would significantly improve toml overall and set it even more apart from other config languages.