-
Notifications
You must be signed in to change notification settings - Fork 1
Description
When we think about crate-layout, we should not only consider our own needs to write code we are able to maintain. (-> TL;DR below ^^).
Here is some example php-code how twig is being used
$loader = new Twig_Loader_Filesystem('views');
$twig = new Twig_Environment($loader, array(
'cache' => 'cache',
));
echo $twig->render('index.html', array('name' => '', 'title' => 'Startpage'));
$optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR);
$twig->addExtension($optimizer);
There are two perspectives (in addition to our maintainer-perspective):
- Perspective of someone using the code (like above)
** he/she will be interested to write someuse twig::{X, Y};
statements that are not tooooo long.
** IMHO still ok: twig::loader::FileSystem, twig::ext::Optimizer - maybe too: long twig::compiler::extension::Optimizer (<- my current layout), but it has a very descriptive signature.
** Either way - this target group should not be too difficult w.r.t crate-layout - Perspective of someone extending the code via custom extensions (instead of forking + patching the repository) - I think this is what Twig is strong at.
** They will be interested to find everything related to extensions at intuitive places with little distractions.
So what must be visible for end-users from outside of the crate must be
- loader
- environment (which I would like to call compiler - which is a bit more specific about what it does)
- extensions (core, debug, optimizer, mustache, whatever)
- lexer options
- compiled templates (because these will be the return values of the compiler - in my mind there may be different variants, like compilation to some TwigRustByteCode, NativeRust, MachineCode or even JavaScript)
- or for template-debugging/-inspection just an AST-representation of a template (i.e. nodes)
- .. everything that is needed to interact with compiled templates (whatever that might be) - maybe we can achieve to keep the functionality self-contained inside of compiled templates (at least from end-user perspective)?
For people writing custom extensions the following must be public too:
- extension api
- error handling
- parser + parser job
- tokens (input) + nodes api and basic nodes (output)
- custom extensions will need to define their own nodes in whatever representation(s) we choose to define.
- we can also allow access to nodes of other extensions - like the if- and for-nodes which should live in the core extension. But we must warn other devs, that even the core extension layout may not be as stable as the public apis of the parser.
So these should be the key players in our public crate layout.
And there should be little distractions for extension devs. So either we have really good documentation or physical layout on disc should resemble the public layout closely, i.e. there shouldn't be too many re-exports all over the place, because that might be confusing for someone trying to understand the code.
The lexer itself does not need to be public - only its options need to be. We could hide away the lexer a little somewhere. You could argue that the lexer would only distract, because it is not needed for developing extensions. And for debugging templates it should be sufficient for most cases to include lexed templates in some pretty-printing verbose error messages. So no need to have the lexer at everyones fingertips..
TL;DR
So here are the important players from before (indentation reflects importance - not necessarily final crate layout) - this should at least influence our choices
END-USER perspective
- compiler
- options
- extension
- core
- ...
- loader
- template
EXTENSION-DEV perspective
..as above..
- dev_stuff
- extension_api
- error
- parser
- tokens / nodes