Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import content from filenames defined in an array

Tags:

d

ctfe

I can concatenate files read by import during compile time like this:

enum string a = import("a.txt");
enum string b = import("b.txt");
enum string result = a ~ b;

How can I get the concatenated result if I have the filenames in an array?

enum files = ["a.txt", "b.txt"];
string result;
foreach (f; files) {
  result ~= import(f);
}

This code returns with an error Error: variable f cannot be read at compile time.

Functional approach doesn't seem to work either:

enum files = ["a.txt", "b.txt"];
enum result = reduce!((a, b) => a ~ import(b))("", files);

It returns with the same error: Error: variable b cannot be read at compile time

like image 304
Tamas Avatar asked Dec 18 '22 23:12

Tamas


2 Answers

Maybe using string mixins?

enum files  = ["test1", "test2", "test3"];

// There may be a better trick than passing the variable name here
string importer(string[] files, string bufferName) {
    string result = "static immutable " ~ bufferName ~ " = ";

    foreach (file ; files[0..$-1])
        result ~= "import(\"" ~ file ~ "\") ~ ";
    result ~= "import(\"" ~ files[$-1] ~ "\");";

    return result;
}

pragma(msg, importer(files, "result"));
// static immutable result = import("test1") ~ import("test2") ~ import("test3");

mixin(importer(files, "result"));
pragma(msg, result)
like image 139
cym13 Avatar answered Jan 06 '23 01:01

cym13


I have found a solution that doesn't use string mixins:

string getit(string[] a)() if (a.length > 0) {
    return import(a[0]) ~ getit!(a[1..$]);
}

string getit(string[] a)() if (a.length == 0) {
    return "";
}

enum files = ["a.txt", "b.txt"];
enum result = getit!files;
like image 29
Tamas Avatar answered Jan 06 '23 01:01

Tamas