Combined parsing and schema generations (libfetchers, WIP)#9273
Combined parsing and schema generations (libfetchers, WIP)#9273roberth wants to merge 12 commits intoNixOS:masterfrom
Conversation
| using namespace testing; | ||
|
|
||
| namespace nix::fetchers { | ||
| using namespace parsers; |
There was a problem hiding this comment.
I think we should deindent these like the rest of the code (and go back and deindent the other indented tests too.
| bool required; | ||
| std::shared_ptr<Schema> type; | ||
| bool operator==(const Attr & other) const; | ||
| }; |
| Attrs() {}; | ||
| Attrs(std::map<std::string, Attr> && attrs) | ||
| : attrs(attrs) {}; | ||
| }; |
|
|
||
| namespace nix::fetchers { | ||
|
|
||
| std::string attrType(const Attr &attr) { |
There was a problem hiding this comment.
| std::string attrType(const Attr &attr) { | |
| std::string attrType(const Attr & attr) { |
our usual format
| /** | ||
| * A primitive value that can be used in a fetcher attribute. | ||
| */ | ||
| typedef std::variant<std::string, uint64_t, Explicit<bool>> Attr; |
There was a problem hiding this comment.
In some later PR we should probably do a wrapper struct (per #7479 (comment)) so the functions below can be methods.
|
|
||
| namespace nix::fetchers { | ||
|
|
||
| struct Schema; |
There was a problem hiding this comment.
I would not indent the outermost namespace
| struct Schema; | |
| struct Schema; |
| std::apply([&](auto&&... args) { (f(args), ...); }, t); | ||
| } | ||
|
|
||
| /** Accepts an 'Attrs'. Composes 'Attr' (singular) parsers. */ |
There was a problem hiding this comment.
| /** Accepts an 'Attrs'. Composes 'Attr' (singular) parsers. */ | |
| /** Accepts an `Attrs`. Composes `Attr` (singular) parsers. */ |
|
|
||
| public: | ||
| Attrs(Callable lambda, AttrParsers *... parsers) | ||
| : lambda(lambda), parsers(parsers...) { |
There was a problem hiding this comment.
| : lambda(lambda), parsers(parsers...) { | |
| : lambda(lambda), parsers(parsers...) | |
| { |
| class Attrs | ||
| : public Parser< | ||
| nix::fetchers::Attrs, | ||
| std::invoke_result_t<Callable, typename AttrParsers::Out ...>> { |
There was a problem hiding this comment.
| std::invoke_result_t<Callable, typename AttrParsers::Out ...>> { | |
| std::invoke_result_t<Callable, typename AttrParsers::Out ...>> | |
| { |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2023-11-03-nix-team-meeting-minutes-100/35245/1 |
We already have some maybeGet*Attr functions - just not one for std::map itself yet.
Name will be used in upcoming commit.
9c75cb8 to
f014413
Compare
| new OptionalAttr<TarballAttrs,Int>("revCount", Int {}, [](auto x) { return x.revCount; }), | ||
| new OptionalAttr<TarballAttrs,Int>("lastModified", Int {}, [](auto x) { return x.lastModified; }) | ||
| ); | ||
| }(); |
There was a problem hiding this comment.
I'm debating whether this is a good solution.
Good:
- it's functional
- we can initialize a
const TarballAttrs - no lists of functions or such, that may slow it down (as it would be nice to have a similar solution that works for defining primops with attr based arguments etc)
- bidirectional
Bad:
- boilerplate
- too little type inference
- unparseAttr is super ad hoc. Doesn't have a proper interface. Just "happy" template accidents.
- making the arguments and parser codecs line up is a manual process and the error messages are useless
Perhaps a Setting-like alternative would be easier to use?
It would allow us to spend some template "budget" on declaring what kinds of fields they are, so that we have a variation of the TarballAttrs to represent a properly locked input, or a variation for the attrs that should be returned by fetchTree.
There was a problem hiding this comment.
Maybe a syntax like this can provide better inference, at the cost of needing another type.
OptionalAttr("revCount", Int {}).getter([](TarballAttrs x){ return x.revCount; })
Regarding the boilerplate - maybe feel quite that way if we make more use of this feature when extended with doc strings.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR #9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR #9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR #9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR NixOS#9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR NixOS#9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
The renaming task is splatting everything together into markdown lists. I think I want to do that with the lowdown AST; I opened kristapsdz/lowdown#131 for this purpose PR #9273 should be able to improve upon this a good bit, but I think it is still a useful stepping stone.
Motivation
By combining parsing and schema generation (for docs), we achieve the following
Eventually, this helps with removing
submodules"leak"TODO
It's currently not useful at all.
Must have
Schemato JSONShould have
typetag node in the schemaNice to have
Context
Priorities
Add 👍 to pull requests you find important.