From 4eb136fabc30b81ecc9728d76eb6e21bbf4a6244 Mon Sep 17 00:00:00 2001 From: JamesChenX Date: Fri, 27 Oct 2023 07:26:07 +0800 Subject: [PATCH] Share `ResponseStatusCodeFileGenerator` --- .../java/ResponseStatusCodeFileGenerator.java | 194 ++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 turms-server-common/src/test/java/ResponseStatusCodeFileGenerator.java diff --git a/turms-server-common/src/test/java/ResponseStatusCodeFileGenerator.java b/turms-server-common/src/test/java/ResponseStatusCodeFileGenerator.java new file mode 100644 index 0000000000..c989833ff9 --- /dev/null +++ b/turms-server-common/src/test/java/ResponseStatusCodeFileGenerator.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2019 The Turms Project + * https://github.com/turms-im/turms + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.List; + +import lombok.SneakyThrows; + +import im.turms.server.common.access.common.ResponseStatusCode; + +/** + * @author James Chen + */ +class ResponseStatusCodeFileGenerator { + + @SneakyThrows + public static void main(String[] args) { + + Class responseStatusCodeClass = ResponseStatusCode.class; + URI dir = responseStatusCodeClass.getProtectionDomain() + .getCodeSource() + .getLocation() + .toURI(); + String filename = responseStatusCodeClass.getCanonicalName() + .replace('.', '/') + + ".java"; + Path path = Path.of(dir) + // \target\classes\ + .resolve("../../src/main/java") + .resolve(filename); + List lines = Files.readAllLines(path); + + // cpp + generateSourceCodeFile("h", lines, 0, (statusCodeName, statusCode, isGroupFirstCode) -> { + String codeName = convertToCamelCase(statusCodeName); + return "const int k" + + codeName.substring(0, 1) + .toUpperCase() + + codeName.substring(1) + + " = " + + statusCode + + ";"; + }); + + // dart + generateSourceCodeFile("dart", + lines, + 2, + (statusCodeName, statusCode, isGroupFirstCode) -> "static const " + + convertToCamelCase(statusCodeName) + + " = " + + statusCode + + ";"); + + // kotlin + generateSourceCodeFile("kt", + lines, + 4, + (statusCodeName, statusCode, isGroupFirstCode) -> "const val " + + statusCodeName + + " = " + + statusCode); + + // typescript + generateSourceCodeFile("ts", + lines, + 4, + (statusCodeName, statusCode, isGroupFirstCode) -> isGroupFirstCode + ? statusCodeName + + " = " + + statusCode + + "," + : statusCodeName + + ","); + + // swift + generateSourceCodeFile("swift", + lines, + 4, + (statusCodeName, statusCode, isGroupFirstCode) -> { + String codeName = convertToCamelCase(statusCodeName); + return isGroupFirstCode + ? "case " + + codeName + + " = " + + statusCode + : "case " + + codeName; + }); + } + + private static String convertToCamelCase(String input) { + String[] words = input.toLowerCase() + .split("_"); + StringBuilder builder = new StringBuilder(64); + int length = words.length; + for (int i = 0; i < length; i++) { + if (i == 0) { + builder.append(words[i]); + } else { + builder.append(Character.toUpperCase(words[i].charAt(0))) + .append(words[i].substring(1)); + } + } + return builder.toString(); + } + + private static void generateSourceCodeFile( + String fileSuffix, + List lines, + int indent, + StatusCodeTransformer transformer) throws IOException { + StringBuilder builder = new StringBuilder(1024 * 16); + boolean start = false; + int lastStatusCode = Integer.MIN_VALUE; + String indentStr = " ".repeat(indent); + for (String line : lines) { + line = line.trim(); + if (!start) { + start = line.startsWith("public enum ResponseStatusCode {"); + continue; + } + if (line.isBlank()) { + builder.append('\n'); + continue; + } + if (line.contains("TODO")) { + continue; + } + if (line.startsWith("//")) { + builder.append(indentStr) + .append(line) + .append('\n'); + continue; + } + if (line.endsWith(";")) { + break; + } + char firstChar = line.charAt(0); + if (firstChar < 'A' || firstChar > 'Z') { + continue; + } + int constructorIndex = line.indexOf('('); + String statusCodeName = line.substring(0, constructorIndex); + String statusCodeStr = + line.substring(constructorIndex + 1, line.indexOf(',', constructorIndex)); + int statusCode; + try { + statusCode = Integer.parseInt(statusCodeStr); + } catch (NumberFormatException e) { + throw new RuntimeException( + "Failed to parse \"" + + statusCodeStr + + "\" as number", + e); + } + String newLine = transformer + .transform(statusCodeName, statusCode, statusCode != lastStatusCode + 1); + builder.append(indentStr) + .append(newLine) + .append('\n'); + lastStatusCode = statusCode; + } + String code = builder.toString(); + Files.writeString(Path.of("./code." + + fileSuffix), + code, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING); + } + + private interface StatusCodeTransformer { + String transform(String statusCodeName, int statusCode, boolean isGroupFirstCode); + } + +} \ No newline at end of file