Skip to content

Commit

Permalink
inlineimport: implement inlineimport
Browse files Browse the repository at this point in the history
Signed-off-by: João Lourenço <[email protected]>
  • Loading branch information
iK4tsu committed Jun 13, 2021
1 parent 569a34b commit 26e7c0b
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions source/taurus/inlineimport.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
module taurus.inlineimport;

/**
Imports a symbol from a module inline. Useful for module dependencies with little
usage.
Checks are done in every symbol, meaning the sequence will fail on the first
invalid symbol. $(BR)
`From` should be used When compiled in **betterC**. Because `from` checks valid
symbols from the start, the program fails if some module depends on something
that isn't supported in **betterC**.
- The following do not compile under `betterC`:
- **`from.std.traits.isIntegral!byte`**
- **`from.std.isIntegral!byte`**
- **`From!"std".isIntegral!byte`**
- The correct way to import is to specify the starting point with `From`:
- **`From!"std.traits".isIntegral!byte`**
Params: mod = module to search from.
Examples:
---
assert(from.std.traits.isIntegral!byte);
assert(From!"std.array".split("Hello.World", ".") == ["Hello", "World"]);
assert(!__traits(compiles, from.not.exists)); // fails at 'not'
---
*/
enum From(string mod) = FromImpl!mod.init;
enum from = From!null; ///

version (D_BetterC) {} else
///
@safe pure nothrow unittest
{
assert(from.std.array.split("Hello.World", ".") == ["Hello", "World"]);
assert(From!"std.array".split("Hello.World", ".") == ["Hello", "World"]);

assert(from.std.split("Hello.World", ".") == ["Hello", "World"]);
assert(From!"std".split("Hello.World", ".") == ["Hello", "World"]);

assert(!__traits(compiles, from._does.not.exist));
}

///
private struct FromImpl(string mod)
{
template opDispatch(string sym)
{
/*
order is important:
- mod is empty -> enum FromImpl!sym
- mod.sym is valid -> enum FromImpl!mod.sym
- mod : sym is valid -> alias sym
*/

static if (!mod.length)
{
static if(!isModule!sym)
alias opDispatch = fail!("Unbale to locate module '" ~ sym ~ "'");
else
enum opDispatch = FromImpl!sym.init;
}

else static if (isModule!(mod, ".", sym))
enum opDispatch = FromImpl!(mod ~ "." ~ sym).init;

else
{
static if(!inModule)
alias opDispatch = fail!("Symbol '" ~ sym ~ "' not found in module '" ~ mod ~ "'");
else
mixin("import ", mod, ":", sym, "; alias opDispatch = ", sym, ";");
}

private enum isModule(T ...) = __traits(compiles, { mixin("import ", T, ";"); });
private enum inModule = __traits(compiles, { mixin("import ", mod, ":", sym, ";"); });

private template fail(string msg)
{
noreturn fail(T ...)(auto ref T t) { static assert (false, msg); }
}
}
}

0 comments on commit 26e7c0b

Please sign in to comment.