Parser for tapir file and transformer. Started on generator.

This commit is contained in:
Johan Maasing 2025-03-15 22:00:42 +01:00
parent f0e2523a3d
commit 743432e071
Signed by: johan
GPG key ID: FFD31BABEE2DEED2
8 changed files with 78 additions and 11 deletions

7
.gitignore vendored
View file

@ -36,11 +36,8 @@ replay_pid*
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/**
*.iml
# AWS User-specific
.idea/**/aws.xml

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
public record EndpointNode(PathsNode paths, HandlerNode handler) {
}

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
public record FieldNode(String name, String type) {
}

View file

@ -0,0 +1,70 @@
package nu.zoom.tapir;
import nu.zoom.tapir.parser.*;
import java.io.IOException;
import java.io.StringReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.Callable;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
@Command(name = "tapirgen", mixinStandardHelpOptions = true, description = "Generate source code from a tapir endpoint specification file.")
public class Generator implements Callable<Integer> {
@Parameters(index = "0", description = "The source tapir file.")
private Path file;
@Option(names = {"-t", "--template"}, description = "The template directory. Default is ~/tapir-templates")
private Path templateDir = Paths.get(System.getProperty("user.dir"), "tapir-templates");
@Option(names = {"-o", "--output"}, description = "The directory to write the gerenated code to. Default is ~/tapir-output")
private Path outputDir = Paths.get(System.getProperty("user.dir"), "tapir-output");
public static void main(String[] args) throws ParseException {
int exitCode = new CommandLine(new Generator()).execute(args);
System.exit(exitCode);
}
@Override
public Integer call() {
try {
validateTemplateDirectory();
validateInputFile();
StringReader reader = new StringReader("foo/bar/baz/ -> fooHandler(id:String, name:NonEmptyString)foo/baz/->bazHandler(nothing:Any)");
var rootNode = new TapirParser(reader).endpoints();
var endpoints = NodeTransformer.transform(rootNode);
rootNode.dump("");
endpoints.forEach(endpoint -> {
System.out.println(endpoint);
});
return 0;
} catch (Exception e) {
System.err.println(e.getMessage());
return 1;
}
}
private void validateTemplateDirectory() throws IOException {
if (!Files.isDirectory(this.templateDir)) {
throw new IllegalArgumentException("Template directory '" + this.templateDir + "' does not exist.");
}
Path endpointTemplate = this.templateDir.resolve("endpoints.ftl") ;
if (Files.notExists(endpointTemplate)) {
throw new IllegalArgumentException("Can not find: '" + endpointTemplate + "'.");
}
}
private void validateInputFile() throws IOException {
if (Files.notExists(this.file)) {
throw new IllegalArgumentException("Input file '" + this.file + "' does not exist.");
}
if (!Files.isReadable(this.file) || !Files.isRegularFile(this.file)) {
throw new IllegalArgumentException("Input file '" + this.file + "' is not a readable file.");
}
}
}

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
import java.util.List;

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
import nu.zoom.tapir.parser.Node;
import nu.zoom.tapir.parser.ParseException;

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
import java.util.List;

View file

@ -1,4 +1,4 @@
package nu.zoom.state;
package nu.zoom.tapir;
import java.nio.file.Path;
import java.util.List;