Skip to content

Commit

Permalink
a lot closer
Browse files Browse the repository at this point in the history
  • Loading branch information
burner committed Jan 8, 2024
1 parent bf800c9 commit 35dd808
Show file tree
Hide file tree
Showing 58 changed files with 1,025 additions and 14,750 deletions.
45 changes: 28 additions & 17 deletions fakerjs2generator/source/app.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import std.array;
import std.stdio;
import std.algorithm.iteration : filter;
import std.file : dirEntries, SpanMode, readText;
import std.algorithm.sorting : sort;
import std.file : DirEntry, dirEntries, SpanMode, readText;
import std.string : lastIndexOf;
import std.uni : toLower;
import std.format;
Expand All @@ -10,33 +12,42 @@ import parser;
import defis;
import generator;

void buildBase() {
string en = "en.json";
JSONValue jv = parseJSON(readText(en));
JsonFile jf = parseJson!(JsonFile)(jv, [en]);
backFillMergeArray(jf);
string langName = en[0 .. $ - 5];
auto f = File("../source/faked/base.d", "w");
genTopMatter(jf, f.lockingTextWriter(), "en", true);
generate(jf.data, f.lockingTextWriter(), [], true);
f.writeln("}");
}

void main() {
genCustomTypes();
buildBase();
foreach(j; dirEntries("", "*.json", SpanMode.shallow)
JsonFile bs = buildBase();
string[] langs;
DirEntry[] entries = dirEntries("", "*.json", SpanMode.shallow)
.filter!(it => it.name != "dub.json")
.filter!(it => it.name != "en.json"))
{
.filter!(it => it.name != "base.json")
.array
.sort!((a,b) => a.name < b.name)
.array;

foreach(j; entries) {
writeln(j.name);
JSONValue jv = parseJSON(readText(j.name));
JsonFile jf = parseJson!(JsonFile)(jv, [j.name]);
backFillMergeArray(jf);
string langName = j.name[0 .. $ - 5];
langs ~= langName;
auto f = File(format("../source/faked/faker_%s.d", langName.toLower()), "w");
genTopMatter(jf, f.lockingTextWriter(), langName, false);
generate(jf.data, f.lockingTextWriter(), [], false);
f.writeln("}");
}
generateForward(bs, langs);
}

JsonFile buildBase() {
string en = "base.json";
JSONValue jv = parseJSON(readText(en));
JsonFile jf = parseJson!(JsonFile)(jv, [en]);
backFillMergeArray(jf);
string langName = en[0 .. $ - 5];
auto f = File("../source/faked/faker_base.d", "w");
genTopMatter(jf, f.lockingTextWriter(), "en", true);
generate(jf.data, f.lockingTextWriter(), [], true);
f.writeln("}\n");
traverseMustachAAs(jf.data, f.lockingTextWriter(), []);
return jf;
}
32 changes: 32 additions & 0 deletions fakerjs2generator/source/defis.d
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ struct Cell_PhoneFolder {

struct ColorFolder {
Nullable!(string[]) human;
Nullable!(string[]) space;
}

struct Product_Name {
Expand Down Expand Up @@ -97,6 +98,9 @@ struct CompanyFolder {

struct DatabaseFolder {
Nullable!(string[]) column;
Nullable!(string[]) collation;
Nullable!(string[]) engine;
Nullable!(string[]) type;
}

struct DateMonth {
Expand Down Expand Up @@ -143,12 +147,33 @@ struct HackerFolder {
Nullable!(string[]) noun;
Nullable!(Mustache[]) phrase;
Nullable!(string[]) verb;
Nullable!(string[]) abbreviation;
}

struct EmojiFolder {
Nullable!(string[]) smiley;
Nullable!(string[]) body_;
Nullable!(string[]) person;
Nullable!(string[]) nature;
Nullable!(string[]) food;
Nullable!(string[]) travel;
Nullable!(string[]) activity;
Nullable!(string[]) object;
Nullable!(string[]) symbol;
Nullable!(string[]) flag;
}

struct InternetFolder {
Nullable!(string[]) domain_suffix;
Nullable!(string[]) example_email;
Nullable!(string[]) free_email;
Nullable!(EmojiFolder) emoji;
}

struct Country_Code {
Nullable!(string) alpha2;
Nullable!(string) alpha3;
Nullable!(string) numeric;
}

struct LocationFolder {
Expand All @@ -170,6 +195,8 @@ struct LocationFolder {
Nullable!(string[]) street_name;
Nullable!(Mustache[]) street_pattern;
Nullable!(string[]) street_suffix;
Nullable!(Country_Code[]) country_code;
Nullable!(string[]) time_zone;
}

struct LoremFolder {
Expand Down Expand Up @@ -254,6 +281,10 @@ struct WordFolder {
Nullable!(string[]) verb;
}

struct SystemFolder {
Nullable!(string[]) directoryPaths;
}

struct Language {
Nullable!AirlineFolder airline;
Nullable!(AnimalFolder) animal;
Expand All @@ -275,6 +306,7 @@ struct Language {
Nullable!(TeamFolder) team;
Nullable!(VehicleFolder) vehicle;
Nullable!(WordFolder) word;
Nullable!(SystemFolder) system;
}

struct JsonFile {
Expand Down
170 changes: 147 additions & 23 deletions fakerjs2generator/source/generator.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,94 @@ import std.sumtype;
import helper;
import defis;

void generateForward(JsonFile bs, string[] langs) {
auto f = File("../source/faked/fakerforwarder.d", "w");
f.writefln(`module faked.fakerforwarder;
import faked.customtypes;
` ~ "%--(%s\n%)" ~ `
class FakerForwarder {
@safe:
Faker[] toPassThrough = [ new Faker(1337), ` ~ "%--(%s, %)" ~ ` ];
`
, langs.map!(l => "import faked.faker_" ~ l.toLower() ~ ";")
, langs.map!(l => "new Faker_" ~ l.toLower() ~ "(1337)")
);

auto ltw = f.lockingTextWriter();
traverseFwd(bs.data, ltw, []);

f.writeln("}");
}

void traverseFwd(T,Out)(T t, ref Out o, string[] path) {
static if(T.stringof.endsWith("Folder")
|| is(T == Language)
|| is(T == Product_Name)
|| is(T == DateWeekday)
|| is(T == Title)
|| is(T == DateMonth))
{
static foreach(string mem; [FieldNameTuple!(T)].filter!(m => !m.empty)) {{
traverseFwd(__traits(getMember, t, mem), o, path ~ mem);
}}
} else static if(is(T == Nullable!F, F)) {
if(!t.isNull()) {
traverseFwd(t.get(), o, path);
}
} else {
string ptfn = pathToFuncName(path);
static if(is(T == string[])) {
iformat(o, 1, "final string %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Mustache[])) {
iformat(o, 1, "final string %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Airplane[])) {
iformat(o, 1, "final Airline %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Airport[])) {
iformat(o, 1, "final Airport %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Currency[])) {
iformat(o, 1, "final Currency %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == ChemicalUnit[])) {
iformat(o, 1, "final ChemicalUnit %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == ChemicalElement[])) {
iformat(o, 1, "final ChemicalElement %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Airline[])) {
iformat(o, 1, "final Airline %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == MustacheWeight[])) {
iformat(o, 1, "final string %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Mustache[string])) {
iformat(o, 1, "final string %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else static if(is(T == Number[])) {
iformat(o, 1, "final string %s() {\n", ptfn);
iformat(o, 2, "return choice(this.toPassThrought, this.rnd).%s();\n\t}\n\n"
, ptfn);
} else {
writefln("Unhandled %s", T.stringof);
}
}
}

void generate(Language lang, string langName, const bool base) {
auto app = appender!string();
traverse(lang, app, [], base);
Expand All @@ -29,6 +117,33 @@ void generate(Out)(Language lang, auto ref Out o, string[] path, const bool base
traverse(lang, o, path, base);
}

void traverseMustachAAs(T,Out)(T t, auto ref Out o, string[] path) {
static if(T.stringof.endsWith("Folder")
|| is(T == Language)
|| is(T == Product_Name)
|| is(T == DateWeekday)
|| is(T == Title)
|| is(T == DateMonth))
{
static foreach(string mem; [FieldNameTuple!(T)].filter!(m => !m.empty)) {{
traverseMustachAAs(__traits(getMember, t, mem), o, path ~ mem);
}}
} else static if(is(T == Nullable!F, F)) {
if(!t.isNull()) {
traverseMustachAAs(t.get(), o, path);
}
} else {
static if(is(T == Mustache[string])) {
string enumName = toFirstUpper(pathToFuncName(path));
formattedWrite(o, "enum %sEnum {\n", enumName);
foreach(idx, key; t.keys()) {
iformat(o, 1, "%s %s\n", idx == 0 ? " " : ",", key);
}
formattedWrite(o, "}\n\n");
}
}
}

void traverse(T,Out)(T t, ref Out o, string[] path, const bool base) {
static if(T.stringof.endsWith("Folder")
|| is(T == Language)
Expand Down Expand Up @@ -89,7 +204,7 @@ void genNumber(Out)(Number[] n, ref Out o, string[] path, const bool base) {
iformat(o, 2, "const string[] strs =\n\t\t[ ");
str80(o, n.map!(it => it.num).array, 2);
o.put(" ];\n\n");
iformat(o, 2, "return numberBuild(choice(str, this.rnd));\n");
iformat(o, 2, "return numberBuild(choice(strs, this.rnd));\n");
iformat(o, 1, "}");
}

Expand Down Expand Up @@ -294,7 +409,7 @@ string mustacheToFuncIdentifer(string s) {

void genCustomTypes() {
auto file = File("../source/faked/customtypes.d", "w");
file.writeln(`module faker.customtypes;
file.writeln(`module faked.customtypes;
import std.typecons : Nullable;
Expand Down Expand Up @@ -335,19 +450,21 @@ struct ChemicalUnit {

void genTopMatter(Out)(ref JsonFile jf, auto ref Out o, const string language, const bool base) {
if(base) {
iformat(o, 0, `module faker.base;
iformat(o, 0, `module faked.faker_base;
import std.random;
import std.algorithm : map, joiner;
import std.array;
import std.format;
import std.conv : to;
import std.string : toUpper;
import std.exception : enforce;
import std.format;
import std.random;
import std.range : iota, take, repeat;
import std.algorithm : map, joiner;
import std.string : toUpper;
import std.typecons : Nullable, nullable;
import faker.customtypes;
import faked.customtypes;
class Faker {
class Faker_base {
@safe:
Random rnd;
this(int seed) {
Expand Down Expand Up @@ -384,31 +501,38 @@ class Faker {
`);
} else {
string chain = jf.chain.length == 1 ? "en" : jf.chain[0];
chain = chain == "en"
? "Faker"
: "Faker_" ~ chain.toLower();
iformat(o, 0, `module faker.faker_%1$s;
writeln(language.toLower, " ", jf.chain);
string chain =
jf.chain.empty
? ""
: (" : Faker_" ~ jf.chain[0].toLower());

import std.random;
string import_ = jf.chain.empty
? ""
: "\nimport faked.faker_" ~ jf.chain[0].toLower() ~ ";";

iformat(o, 0, `module faked.faker_%1$s;
import std.algorithm : map, joiner;
import std.array;
import std.format;
import std.conv : to;
import std.string : toUpper;
import std.exception : enforce;
import std.format;
import std.random;
import std.range : iota, take, repeat;
import std.algorithm : map, joiner;
import std.string : toUpper;
import std.typecons : Nullable, nullable;
import faker.customtypes;
import faker.base;%3$s
import faked.customtypes;
%3$s
class Faker_%1$s : %2$s {
class Faker_%1$s%2$s {
@safe:
this(int seed) {
super(seed);
}
`, language.toLower(), chain
, chain != "Faker" ? "\nimport faker.faker_%s;".format(jf.chain[0].toLower()) : "");
`, language.toLower(), chain, import_);
}
}

Expand Down
Loading

0 comments on commit 35dd808

Please sign in to comment.