Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions annotation/src/main/java/online/sharedtype/SharedType.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
* <p>
* <b>Configurations:</b><br>
* Global properties can be defined in a client provided property file or system properties.
* By default, SharedType will look for file name "sharedtype.properties" on cmd current path.
* By default, SharedType will look for file name "sharedtype.properties" on cmd path.
* The property file path can be changed via compiler option "sharedtype.propsFile", see web for details.
* System properties will override property file values.
* Configs on class level (via this annotation) will take precedence over global properties.
* Some properties are also defined at class level, i.e. via this annotation, which will take precedence over global properties.
* </p>
*
* <p>
Expand Down Expand Up @@ -121,6 +121,14 @@
* Type mapped this way will take the highest precedence.
* E.g. a date type is configured to be emitted as string, you can override the particular mapping to emit a {@code Date}.
* Type mapping will override name configured in {@link SharedType#name()}.
* </p><br>
*
* <p>
* <b>Custom code snippet:</b><br>
* Clients can provide custom code snippets to be injected into the emitted file.
* This can be useful when e.g. a 3rd party type is referenced at client code.
* By default, SharedType will search files "sharedtype-custom-code.ts", "sharedtype-custom-code.rs" respectively on cmd path.
* File paths can be configured via global properties.
* </p>
*
* <br>
Expand Down
4 changes: 4 additions & 0 deletions client-test/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
mod types;

pub static CUSTOM_CODE_TYPE: types::CustomInjectedStruct = types::CustomInjectedStruct {
field: 33,
};

#[cfg(test)]
mod tests {
use std::collections::HashMap;
Expand Down
316 changes: 158 additions & 158 deletions client-test/typescript/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client-test/typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"description": "typescript-client-test",
"devDependencies": {
"typescript": "5.6.3",
"vitest": "3.0.9"
"vitest": "3.1.1"
}
}
5 changes: 4 additions & 1 deletion client-test/typescript/src/types.java8.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JavaClass } from "./index.java8.js";
import type { CustomCode, JavaClass } from "./index.java8.js";

export const javaClass: JavaClass = {
string: "",
Expand All @@ -7,3 +7,6 @@ export const javaClass: JavaClass = {
a: 0,
value: 0
};

export const customCodeType: CustomCode = {
}
10 changes: 10 additions & 0 deletions doc/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ You can customize the path by config `maven-compiler-plugin`:
</compilerArgs>
```

Properties can also be passed in as system properties, which will override the properties files, e.g.
```bash
./mvnw clean compile -Dsharedtype.typescript.custom-code-path=it/custom-code.ts
```
or
```bash
MAVEN_OPTS="-Dsharedtype.typescript.custom-code-path=it/custom-code.ts" ./mvnw clean compile
```
or can use [properties-maven-plugin](https://www.mojohaus.org/properties-maven-plugin/usage.html#set-system-properties) to set system properties for the build.

See [Default Properties](../processor/src/main/resources/sharedtype-default.properties) for details.

#### Per annotation options
Expand Down
4 changes: 4 additions & 0 deletions it/custom-code.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// test code snippet
pub struct CustomInjectedStruct {
pub field: i32,
}
3 changes: 3 additions & 0 deletions it/custom-code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// test code snippet
export interface CustomCode {
}
24 changes: 24 additions & 0 deletions it/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,30 @@
<includes>${compileClasses}</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>set-system-properties</goal>
</goals>
<configuration>
<properties>
<property>
<name>sharedtype.typescript.custom-code-path</name>
<value>it/custom-code.ts</value>
</property>
<property>
<name>sharedtype.rust.custom-code-path</name>
<value>it/custom-code.rs</value>
</property>
</properties>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public static final class Typescript {
private final EnumFormat enumFormat;
private final FieldReadonlyType fieldReadonlyType;
private final Map<String, String> typeMappings;
private final String customCodePath;

@Getter
public enum OptionalFieldFormat {
Expand Down Expand Up @@ -88,5 +89,6 @@ public static final class Rust {
private final Set<String> defaultTypeMacros;
private final String targetDatetimeTypeLiteral;
private final Map<String, String> typeMappings;
private final String customCodePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ private static Props loadProps(Properties properties) {
.enumFormat(parseEnum(properties, "sharedtype.typescript.enum-format", Props.Typescript.EnumFormat::fromString))
.fieldReadonlyType(parseEnum(properties, "sharedtype.typescript.field-readonly-type", Props.Typescript.FieldReadonlyType::fromString))
.typeMappings(parseMap(properties, "sharedtype.typescript.type-mappings"))
.customCodePath(properties.getProperty("sharedtype.typescript.custom-code-path"))
.build())
.rust(Props.Rust.builder()
.outputFileName(properties.getProperty("sharedtype.rust.output-file-name"))
Expand All @@ -72,6 +73,7 @@ private static Props loadProps(Properties properties) {
.defaultTypeMacros(splitArray(properties.getProperty("sharedtype.rust.default-macros-traits")))
.targetDatetimeTypeLiteral(properties.getProperty("sharedtype.rust.target-datetime-type"))
.typeMappings(parseMap(properties, "sharedtype.rust.type-mappings"))
.customCodePath(properties.getProperty("sharedtype.rust.custom-code-path"))
.build())
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import online.sharedtype.processor.domain.ConstantNamespaceDef;
import online.sharedtype.processor.domain.TypeDef;
import online.sharedtype.processor.writer.adaptor.RenderDataAdaptor;
import online.sharedtype.processor.writer.adaptor.RenderDataAdaptorFactory;
import online.sharedtype.processor.writer.converter.TemplateDataConverter;
import online.sharedtype.processor.writer.render.Template;
import online.sharedtype.processor.writer.render.TemplateRenderer;
Expand All @@ -29,14 +30,14 @@
final class TemplateTypeFileWriter implements TypeWriter {
private final Context ctx;
private final TemplateRenderer renderer;
private final Template headerTemplate;
private final RenderDataAdaptorFactory renderDataAdaptorFactory;
private final Set<TemplateDataConverter> converters;
private final String outputFileName;

@Override
public void write(List<TypeDef> typeDefs) throws IOException {
List<Tuple<Template, Object>> data = new ArrayList<>(typeDefs.size() * converters.size());
data.add(Tuple.of(headerTemplate, RenderDataAdaptor.header(ctx)));
List<Tuple<Template, ?>> data = new ArrayList<>(typeDefs.size() * converters.size());
data.add(renderDataAdaptorFactory.header(ctx));

Map<String, TypeDef> simpleNames = new HashMap<>(typeDefs.size());
for (TypeDef typeDef : typeDefs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import online.sharedtype.processor.domain.TypeDef;
import online.sharedtype.processor.context.Context;
import online.sharedtype.processor.context.OutputTarget;
import online.sharedtype.processor.writer.adaptor.RenderDataAdaptorFactory;
import online.sharedtype.processor.writer.converter.TemplateDataConverter;
import online.sharedtype.processor.writer.render.Template;
import online.sharedtype.processor.writer.render.TemplateRenderer;

import java.io.IOException;
Expand Down Expand Up @@ -38,12 +38,12 @@ static TypeWriter create(Context ctx) {
TemplateRenderer renderer = TemplateRenderer.create();
if (ctx.getProps().getTargets().contains(OutputTarget.TYPESCRIPT)) {
writers.add(new TemplateTypeFileWriter(
ctx, renderer, Template.TEMPLATE_TYPESCRIPT_HEADER, TemplateDataConverter.typescript(ctx), ctx.getProps().getTypescript().getOutputFileName()
ctx, renderer, RenderDataAdaptorFactory::typescript, TemplateDataConverter.typescript(ctx), ctx.getProps().getTypescript().getOutputFileName()
));
}
if (ctx.getProps().getTargets().contains(OutputTarget.RUST)) {
writers.add(new TemplateTypeFileWriter(
ctx, renderer, Template.TEMPLATE_RUST_HEADER, TemplateDataConverter.rust(ctx), ctx.getProps().getRust().getOutputFileName()
ctx, renderer, RenderDataAdaptorFactory::rust, TemplateDataConverter.rust(ctx), ctx.getProps().getRust().getOutputFileName()
));
}
return new CompositeWriter(writers);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package online.sharedtype.processor.writer.adaptor;

import lombok.RequiredArgsConstructor;
import online.sharedtype.processor.context.Context;
import online.sharedtype.processor.context.RenderFlags;
import online.sharedtype.processor.support.exception.SharedTypeException;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@RequiredArgsConstructor
abstract class AbstractDataAdaptor implements RenderDataAdaptor {
final Context ctx;

final RenderFlags renderFlags() {
return ctx.getRenderFlags();
}

abstract String customCodeSnippet();

static String readCustomCodeSnippet(String path) {
Path customCodePath = Paths.get(path);
if (Files.notExists(customCodePath)) {
return "";
}

try {
return new String(Files.readAllBytes(customCodePath));
} catch (IOException e) {
throw new SharedTypeException(String.format("Failed to read custom code snippet from path '%s'", customCodePath), e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package online.sharedtype.processor.writer.adaptor;

import online.sharedtype.processor.context.Context;

/**
* Implementations of the type is used as render objects feeding to template renderer.
* @author Cause Chung
*/
public interface RenderDataAdaptor {
static RenderDataAdaptor header(Context ctx) {
return new RustHeaderDataAdaptor(ctx);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package online.sharedtype.processor.writer.adaptor;

import online.sharedtype.processor.context.Context;
import online.sharedtype.processor.support.utils.Tuple;
import online.sharedtype.processor.writer.render.Template;

public interface RenderDataAdaptorFactory {
Tuple<Template, RenderDataAdaptor> header(Context ctx);

static Tuple<Template, RenderDataAdaptor> typescript(Context ctx) {
return Tuple.of(Template.TEMPLATE_TYPESCRIPT_HEADER, new TypescriptHeaderDataAdaptor(ctx));
}

static Tuple<Template, RenderDataAdaptor> rust(Context ctx) {
return Tuple.of(Template.TEMPLATE_RUST_HEADER, new RustHeaderDataAdaptor(ctx));
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package online.sharedtype.processor.writer.adaptor;

import lombok.RequiredArgsConstructor;
import online.sharedtype.processor.context.Context;
import online.sharedtype.processor.context.Props;
import online.sharedtype.processor.context.RenderFlags;

import java.util.LinkedHashSet;
import java.util.Set;

@RequiredArgsConstructor
final class RustHeaderDataAdaptor implements RenderDataAdaptor {
private final Context ctx;

RenderFlags renderFlags() {
return ctx.getRenderFlags();
final class RustHeaderDataAdaptor extends AbstractDataAdaptor {
RustHeaderDataAdaptor(Context ctx) {
super(ctx);
}

String allowExpr() {
Expand All @@ -29,4 +24,9 @@ String allowExpr() {

return allows.isEmpty() ? null : String.format("#![allow(%s)]", String.join(", ", allows));
}

@Override
String customCodeSnippet() {
return readCustomCodeSnippet(ctx.getProps().getRust().getCustomCodePath());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package online.sharedtype.processor.writer.adaptor;

import online.sharedtype.processor.context.Context;

final class TypescriptHeaderDataAdaptor extends AbstractDataAdaptor {
TypescriptHeaderDataAdaptor(Context ctx) {
super(ctx);
}

@Override
String customCodeSnippet() {
return readCustomCodeSnippet(ctx.getProps().getTypescript().getCustomCodePath());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ final class MustacheTemplateRenderer implements TemplateRenderer {
private final MustacheFactory mf;

@Override
public void render(Writer writer, List<Tuple<Template, Object>> data) {
for (Tuple<Template, Object> tuple : data) {
public void render(Writer writer, List<Tuple<Template, ?>> data) {
for (Tuple<Template, ?> tuple : data) {
Template template = tuple.a();
Object values = tuple.b();
Mustache mustache = mf.compile(template.getResourcePath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public interface TemplateRenderer {
* @param writer java.io.Writer
* @param data a list of tuple containing the template and corresponding data for rendering.
*/
void render(Writer writer, List<Tuple<Template, Object>> data);
void render(Writer writer, List<Tuple<Template, ?>> data);

static TemplateRenderer create() {
return new MustacheTemplateRenderer(new DefaultMustacheFactory());
Expand Down
10 changes: 10 additions & 0 deletions processor/src/main/resources/sharedtype-default.properties
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ sharedtype.typescript.field-readonly-type=acyclic
## mypackage.MyType2:Type2
sharedtype.typescript.type-mappings=

## Path to custom code snippet file, code snippet in the file will be injected into the top of generated file
## If the file does not exist, it will be ignored
## Below default assumes the file is on the cmd execution path
sharedtype.typescript.custom-code-path=sharedtype-custom-code.ts

############################
# Rust specific properties #
############################
Expand All @@ -96,3 +101,8 @@ sharedtype.rust.target-datetime-type=String
## sharedtype.rust.type-mappings=mypackage.MyType1:Type1,\
## mypackage.MyType2:Type2
sharedtype.rust.type-mappings=

## Path to custom code snippet file, code snippet in the file will be injected into the top of generated file
## If the file does not exist, it will be ignored
## Below default assumes the file is on the cmd execution path
sharedtype.rust.custom-code-path=sharedtype-custom-code.rs
2 changes: 2 additions & 0 deletions processor/src/main/resources/templates/rust/header.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
{{#renderFlags.useRustAny}}use std::any::Any;{{/renderFlags.useRustAny}}
{{#renderFlags.useRustMap}}use std::collections::HashMap;{{/renderFlags.useRustMap}}

{{{customCodeSnippet}}}

Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// Code generated by https://github.com/SharedType/sharedtype

{{{customCodeSnippet}}}

Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void loadDefaultProps() {
assertThat(typescriptProps.getEnumFormat()).isEqualTo(Props.Typescript.EnumFormat.UNION);
assertThat(typescriptProps.getFieldReadonlyType()).isEqualTo(Props.Typescript.FieldReadonlyType.ACYCLIC);
assertThat(typescriptProps.getTypeMappings()).isEmpty();
assertThat(typescriptProps.getCustomCodePath()).isEqualTo("sharedtype-custom-code.ts");

Props.Rust rustProps = props.getRust();
assertThat(rustProps.getOutputFileName()).isEqualTo("types.rs");
Expand All @@ -60,6 +61,7 @@ void loadDefaultProps() {
assertThat(rustProps.getDefaultTypeMacros()).containsExactly("Debug");
assertThat(rustProps.getTargetDatetimeTypeLiteral()).isEqualTo("String");
assertThat(rustProps.getTypeMappings()).isEmpty();
assertThat(rustProps.getCustomCodePath()).isEqualTo("sharedtype-custom-code.rs");
}

@Test
Expand Down
Loading