Skip to content

Commit

Permalink
feat: support rust types
Browse files Browse the repository at this point in the history
  • Loading branch information
plantain-00 committed May 5, 2018
1 parent dc8e2c5 commit 6cc42d7
Show file tree
Hide file tree
Showing 12 changed files with 481 additions and 41 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![npm version](https://badge.fury.io/js/types-as-schema.svg)](https://badge.fury.io/js/types-as-schema)
[![Downloads](https://img.shields.io/npm/dm/types-as-schema.svg)](https://www.npmjs.com/package/types-as-schema)

Genetate json scheme, protobuf file, graphQL schema and reasonml/ocaml types from typescript types.
Genetate json scheme, protobuf file, graphQL schema and reasonml/ocaml/rust types from typescript types.

## supported types features

Expand All @@ -33,7 +33,7 @@ Genetate json scheme, protobuf file, graphQL schema and reasonml/ocaml types fro

## usage

`types-as-schema demo/types.ts --json demo/ --protobuf demo/types.proto --graphql demo/types.gql --reason demo/types.re --ocaml demo/types.ml --debug demo/debug.json`
`types-as-schema demo/types.ts --json demo/ --protobuf demo/types.proto --graphql demo/types.gql --reason demo/types.re --ocaml demo/types.ml --rust demo/types.rs --debug demo/debug.json`

parameters | description
--- | ---
Expand All @@ -42,6 +42,7 @@ parameters | description
`--graphql` | generated graphql schema file
`--reason` | generated reason types file
`--ocaml` | generated ocaml types file
`--rust` | generated rust types file
`--debug` | generated file with debug information in it
`--watch` or `-w` | watch mode

Expand Down
2 changes: 1 addition & 1 deletion clean-scripts.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ module.exports = {
},
revStaticCommand,
{
default: 'node ./dist/index.js demo/cases.ts --json demo/ --debug demo/debug.json --protobuf demo/cases.proto --graphql demo/cases.gql --reason demo/cases.re --ocaml demo/cases.ml',
default: 'node ./dist/index.js demo/cases.ts --json demo/ --debug demo/debug.json --protobuf demo/cases.proto --graphql demo/cases.gql --reason demo/cases.re --ocaml demo/cases.ml --rust demo/cases.rs',
logTool: 'node ./dist/index.js demo/log-tool/types.ts --json demo/log-tool/ --debug demo/log-tool/debug.json --protobuf demo/log-tool/protocol.proto --graphql demo/log-tool/protocol.gql',
matchCalculator: 'node ./dist/index.js demo/match-calculator/types.ts --json demo/match-calculator/ --debug demo/match-calculator/debug.json',
baogame: 'node ./dist/index.js demo/baogame/common.ts --protobuf demo/baogame/protocol.proto --graphql demo/baogame/protocol.gql --debug demo/baogame/debug.json'
Expand Down
255 changes: 255 additions & 0 deletions demo/cases.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
extern crate serde;

pub use self::serde::ser::{Serialize, Serializer};
pub use self::serde::de::{Deserialize, Deserializer, Error};

#[derive(Debug)]
pub enum StringEnum {
EnumMember1,
EnumMember2,
}

impl Serialize for StringEnum {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(match *self {
StringEnum::EnumMember1 => "enum member 1",
StringEnum::EnumMember2 => "enum member 2",
})
}
}

impl<'de> Deserialize<'de> for StringEnum {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
match s.as_str() {
"enum member 1" => Ok(StringEnum::EnumMember1),
"enum member 2" => Ok(StringEnum::EnumMember2),
_ => Err(Error::custom("wrong enum value.")),
}
}
}

#[derive(Serialize, Deserialize, Debug)]
pub enum NumberEnum {
EnumMember1 = 0,
EnumMember2 = 1,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum NumberEnum2 {
EnumMember1 = 3,
EnumMember2 = 4,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeLiteral {
#[serde(rename = "typeLiteralMember1")] pub type_literal_member_1: f32,
#[serde(rename = "typeLiteralMember2")] pub type_literal_member_2: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Interface {
#[serde(rename = "interfaceMember1")] pub interface_member_1: Option<f32>,
#[serde(rename = "interfaceMember2")] pub interface_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnion1 {
#[serde(rename = "typeLiteralMember1")] pub type_literal_member_1: Option<f32>,
#[serde(rename = "typeLiteralMember2")] pub type_literal_member_2: Option<String>,
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: Option<f32>,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnion2 {
pub kind: StringEnum,
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: Option<String>,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnion3 {
pub kind: NumberEnum,
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: Option<String>,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnion4 {
pub kind: String,
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: Option<String>,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub enum TypeUnion5 {
TypeLiteral(TypeLiteral),
Interface(Interface),
}

#[derive(Serialize, Deserialize, Debug)]
pub enum TypeUnion8 {
String(String),
String(String),
bool(bool),
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnion {
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: TypeUnion1,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: TypeUnion2,
#[serde(rename = "typeUnionMember3")] pub type_union_member_3: TypeUnion3,
#[serde(rename = "typeUnionMember4")] pub type_union_member_4: TypeUnion4,
#[serde(rename = "typeUnionMember5")] pub type_union_member_5: TypeUnion5,
#[serde(rename = "typeUnionMember7")] pub type_union_member_7: String,
#[serde(rename = "typeUnionMember8")] pub type_union_member_8: TypeUnion8,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct InterfaceExtends {
#[serde(rename = "interfaceExtendsMember1")] pub interface_extends_member_1: f32,
#[serde(rename = "interfaceExtendsMember2")] pub interface_extends_member_2: String,
#[serde(rename = "interfaceMember1")] pub interface_member_1: Option<f32>,
#[serde(rename = "interfaceMember2")] pub interface_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeIntersection1 {
#[serde(rename = "interfaceMember1")] pub interface_member_1: Option<f32>,
#[serde(rename = "interfaceMember2")] pub interface_member_2: Option<String>,
#[serde(rename = "typeIntersectionMember1")] pub type_intersection_member_1: f32,
#[serde(rename = "typeIntersectionMember2")] pub type_intersection_member_2: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeIntersection2 {
#[serde(rename = "typeIntersectionMember1")] pub type_intersection_member_1: f32,
#[serde(rename = "typeIntersectionMember2")] pub type_intersection_member_2: String,
#[serde(rename = "typeIntersectionMember3")] pub type_intersection_member_3: f32,
#[serde(rename = "typeIntersectionMember4")] pub type_intersection_member_4: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeIntersection {
#[serde(rename = "typeIntersectionMember1")] pub type_intersection_member_1: TypeIntersection1,
#[serde(rename = "typeIntersectionMember2")] pub type_intersection_member_2: TypeIntersection2,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TypeUnionAndIntersection {
#[serde(rename = "typeIntersectionMember1")] pub type_intersection_member_1: f32,
pub kind: NumberEnum,
#[serde(rename = "typeUnionMember1")] pub type_union_member_1: Option<String>,
#[serde(rename = "typeUnionMember2")] pub type_union_member_2: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct TaggedField {
#[serde(rename = "taggedFieldMember1")] pub tagged_field_member_1: f32,
#[serde(rename = "taggedFieldMember2")] pub tagged_field_member_2: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Enum {
#[serde(rename = "stringEnum")] pub string_enum: String,
#[serde(rename = "numberEnum")] pub number_enum: NumberEnum,
#[serde(rename = "numberEnum2")] pub number_enum_2: NumberEnum2,
#[serde(rename = "stringEnum2")] pub string_enum_2: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct NumberType {
#[serde(rename = "numberMember")] pub number_member: f32,
#[serde(rename = "integerMember")] pub integer_member: i32,
#[serde(rename = "uint32Member")] pub uint_32_member: u32,
#[serde(rename = "int32Member")] pub int_32_member: i32,
#[serde(rename = "sint32Member")] pub sint_32_member: i32,
#[serde(rename = "fixed32Member")] pub fixed_32_member: u32,
#[serde(rename = "sfixed32Member")] pub sfixed_32_member: i32,
#[serde(rename = "uint64Member")] pub uint_64_member: u64,
#[serde(rename = "int64Member")] pub int_64_member: i64,
#[serde(rename = "sint64Member")] pub sint_64_member: i64,
#[serde(rename = "fixed64Member")] pub fixed_64_member: u64,
#[serde(rename = "sfixed64Member")] pub sfixed_64_member: i64,
#[serde(rename = "floatMember")] pub float_member: f32,
#[serde(rename = "doubleMember")] pub double_member: f64,
#[serde(rename = "titleMember")] pub title_member: f32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct StringType {
#[serde(rename = "stringMember")] pub string_member: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ArrayType {
#[serde(rename = "arrayType1")] pub array_type_1: Vec<String>,
#[serde(rename = "arrayType2")] pub array_type_2: Vec<TypeLiteral>,
#[serde(rename = "arrayType4")] pub array_type_4: Vec<u32>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct MapType7 {
pub foo: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct MapType {
#[serde(rename = "mapType7")] pub map_type_7: MapType7,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Parameter {
#[serde(rename = "member1")] pub member_1: String,
#[serde(rename = "member2")] pub member_2: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct DefaultValue {
#[serde(rename = "stringMember")] pub string_member: String,
#[serde(rename = "numberMember")] pub number_member: f32,
#[serde(rename = "booleanMember")] pub boolean_member: bool,
#[serde(rename = "stringMember2")] pub string_member_2: String,
#[serde(rename = "stringMember3")] pub string_member_3: String,
#[serde(rename = "numberMember1")] pub number_member_1: i32,
#[serde(rename = "objectMember2")] pub object_member_2: TypeLiteral,
}

type TypeReferenceMember2 = TypeLiteral;

#[derive(Serialize, Deserialize, Debug)]
pub struct ReferenceType {
#[serde(rename = "typeReferenceMember1")] pub type_reference_member_1: TypeLiteral,
#[serde(rename = "typeReferenceMember2")] pub type_reference_member_2: TypeReferenceMember2,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct EntryType {
#[serde(rename = "optionalMember")] pub optional_member: Option<String>,
#[serde(rename = "booleanMember")] pub boolean_member: bool,
#[serde(rename = "stringMember")] pub string_member: String,
#[serde(rename = "numberType")] pub number_type: NumberType,
#[serde(rename = "arrayType")] pub array_type: ArrayType,
#[serde(rename = "referenceType")] pub reference_type: ReferenceType,
#[serde(rename = "interfaceType")] pub interface_type: Interface,
#[serde(rename = "typeUnion")] pub type_union: TypeUnion,
#[serde(rename = "interfaceExtends")] pub interface_extends: InterfaceExtends,
#[serde(rename = "typeIntersection")] pub type_intersection: TypeIntersection,
#[serde(rename = "typeUnionAndIntersection")] pub type_union_and_intersection: TypeUnionAndIntersection,
#[serde(rename = "mapType")] pub map_type: MapType,
#[serde(rename = "taggedField")] pub tagged_field: TaggedField,
pub enum: Enum,
#[serde(rename = "stringNumber")] pub string_number: StringType,
pub id: ID,
pub parameter: Parameter,
#[serde(rename = "optionalArrayMember")] pub optional_array_member: Option<Vec<String>>,
#[serde(rename = "tupleType")] pub tuple_type: Vec<String>,
#[serde(rename = "defaultType")] pub default_type: DefaultValue,
}
3 changes: 2 additions & 1 deletion online/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@
.json-schema,
.graphql-schema,
.reason-types,
.ocaml-types {
.ocaml-types,
.rust-types {
display: block;
padding: 9.5px;
margin: 3px 0 10px 3px;
Expand Down
1 change: 1 addition & 0 deletions online/index.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
<pre class="graphql-schema" v-if="selectedOption === 'graphql schema'">{{graphqlSchema}}</pre>
<pre class="reason-types" v-if="selectedOption === 'reason types'">{{reasonTypes}}</pre>
<pre class="ocaml-types" v-if="selectedOption === 'ocaml types'">{{ocamlTypes}}</pre>
<pre class="rust-types" v-if="selectedOption === 'rust types'">{{rustTypes}}</pre>
</div>
</div>
17 changes: 10 additions & 7 deletions online/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class App extends Vue {
graphqlSchema = ''
reasonTypes = ''
ocamlTypes = ''
rustTypes = ''
private innerSource = localStorage.getItem(localStorageKey) || demoCasesTs
private jsonSchemas: { entry: string; content: string }[] = []

Expand Down Expand Up @@ -45,25 +46,27 @@ export class App extends Vue {
const generator = new Generator(sourceFile)

this.protobuf = generator.generateProtobuf()
this.options = ['protobuf']

this.jsonSchemas = generator.generateJsonSchemas().map(s => ({
entry: s.entry,
content: JSON.stringify(s.schema, null, ' ')
}))
for (const schema of this.jsonSchemas) {
this.options.push(schema.entry)
}

this.graphqlSchema = generator.generateGraphqlSchema()
this.options.push('graphql schema')

this.reasonTypes = generator.generateReasonTypes()
this.options.push('reason types')

this.ocamlTypes = generator.generateOcamlTypes()

this.options = ['protobuf']
for (const schema of this.jsonSchemas) {
this.options.push(schema.entry)
}
this.options.push('graphql schema')
this.options.push('reason types')
this.options.push('ocaml types')

this.rustTypes = generator.generateRustTypes()
this.options.push('rust types')
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion online/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ export type EntryType = {
}
`
// @ts-ignore
export function indexTemplateHtml(this: App) {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"app"},[_c('textarea',{directives:[{name:"model",rawName:"v-model",value:(_vm.source),expression:"source"}],staticClass:"source",domProps:{"value":(_vm.source)},on:{"input":function($event){if($event.target.composing){ return; }_vm.source=$event.target.value}}}),_vm._v(" "),_c('div',{staticClass:"result"},[_c('button',{on:{"click":function($event){_vm.generate()}}},[_vm._v("generate")]),_vm._v(" "),_c('div',{staticClass:"options"},[_c('select',{directives:[{name:"model",rawName:"v-model",value:(_vm.selectedOption),expression:"selectedOption"}],on:{"change":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return val}); _vm.selectedOption=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.options),function(option){return _c('option',{key:option,domProps:{"value":option}},[_vm._v(_vm._s(option))])}))]),_vm._v(" "),(_vm.selectedOption === 'protobuf')?_c('pre',{staticClass:"protobuf"},[_vm._v(_vm._s(_vm.protobuf))]):_vm._e(),_vm._v(" "),(_vm.jsonSchema)?_c('pre',{staticClass:"json-schema"},[_vm._v(_vm._s(_vm.jsonSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'graphql schema')?_c('pre',{staticClass:"graphql-schema"},[_vm._v(_vm._s(_vm.graphqlSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'reason types')?_c('pre',{staticClass:"reason-types"},[_vm._v(_vm._s(_vm.reasonTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'ocaml types')?_c('pre',{staticClass:"ocaml-types"},[_vm._v(_vm._s(_vm.ocamlTypes))]):_vm._e()])])}
export function indexTemplateHtml(this: App) {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"app"},[_c('textarea',{directives:[{name:"model",rawName:"v-model",value:(_vm.source),expression:"source"}],staticClass:"source",domProps:{"value":(_vm.source)},on:{"input":function($event){if($event.target.composing){ return; }_vm.source=$event.target.value}}}),_vm._v(" "),_c('div',{staticClass:"result"},[_c('button',{on:{"click":function($event){_vm.generate()}}},[_vm._v("generate")]),_vm._v(" "),_c('div',{staticClass:"options"},[_c('select',{directives:[{name:"model",rawName:"v-model",value:(_vm.selectedOption),expression:"selectedOption"}],on:{"change":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = "_value" in o ? o._value : o.value;return val}); _vm.selectedOption=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},_vm._l((_vm.options),function(option){return _c('option',{key:option,domProps:{"value":option}},[_vm._v(_vm._s(option))])}))]),_vm._v(" "),(_vm.selectedOption === 'protobuf')?_c('pre',{staticClass:"protobuf"},[_vm._v(_vm._s(_vm.protobuf))]):_vm._e(),_vm._v(" "),(_vm.jsonSchema)?_c('pre',{staticClass:"json-schema"},[_vm._v(_vm._s(_vm.jsonSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'graphql schema')?_c('pre',{staticClass:"graphql-schema"},[_vm._v(_vm._s(_vm.graphqlSchema))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'reason types')?_c('pre',{staticClass:"reason-types"},[_vm._v(_vm._s(_vm.reasonTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'ocaml types')?_c('pre',{staticClass:"ocaml-types"},[_vm._v(_vm._s(_vm.ocamlTypes))]):_vm._e(),_vm._v(" "),(_vm.selectedOption === 'rust types')?_c('pre',{staticClass:"rust-types"},[_vm._v(_vm._s(_vm.rustTypes))]):_vm._e()])])}
// @ts-ignore
export var indexTemplateHtmlStatic = [ ]
// tslint:enable
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"ajv": "6.4.0",
"chokidar": "2.0.3",
"fs-extra": "5.0.0",
"lodash.snakecase": "4.1.1",
"minimist": "1.2.0",
"protobufjs": "6.8.6",
"typescript": "2.8.3"
Expand Down
5 changes: 5 additions & 0 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { generateJsonSchemas, ArrayDefinition, ObjectDefinition, UndefinedDefini
import { generateGraphqlSchema } from './graphql-schema-generator'
import { generateReasonTypes } from './reason-type-generator'
import { generateOcamlTypes } from './ocaml-type-generator'
import { generateRustTypes } from './rust-type-generator'
import { TypeDeclaration } from './utils'

export class Generator {
Expand Down Expand Up @@ -34,6 +35,10 @@ export class Generator {
generateOcamlTypes() {
return generateOcamlTypes(this.declarations)
}

generateRustTypes() {
return generateRustTypes(this.declarations)
}
}

export { ArrayDefinition, ObjectDefinition, UndefinedDefinition }
Loading

0 comments on commit 6cc42d7

Please sign in to comment.