fix object type parsing from jsonschema, and type code generation
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
module generator
|
module generator
|
||||||
|
|
||||||
import freeflowuniverse.herolib.core.code { Folder, IFile, VFile, CodeItem, File, Function, Param, Import, Module, Struct, CustomCode }
|
import freeflowuniverse.herolib.core.code { Array, Folder, IFile, VFile, CodeItem, File, Function, Param, Import, Module, Struct, CustomCode, Result }
|
||||||
import freeflowuniverse.herolib.core.texttools
|
import freeflowuniverse.herolib.core.texttools
|
||||||
import freeflowuniverse.herolib.schemas.openrpc.codegen {content_descriptor_to_parameter}
|
import freeflowuniverse.herolib.schemas.openrpc.codegen {content_descriptor_to_parameter}
|
||||||
import freeflowuniverse.herolib.baobab.specification {ActorMethod, ActorSpecification}
|
import freeflowuniverse.herolib.baobab.specification {ActorMethod, ActorSpecification}
|
||||||
@@ -42,10 +42,11 @@ pub fn generate_methods_file(spec ActorSpecification) !VFile {
|
|||||||
// returns bodyless method prototype
|
// returns bodyless method prototype
|
||||||
pub fn generate_method_function(actor_name string, method ActorMethod) !Function {
|
pub fn generate_method_function(actor_name string, method ActorMethod) !Function {
|
||||||
actor_name_pascal := texttools.name_fix_snake_to_pascal(actor_name)
|
actor_name_pascal := texttools.name_fix_snake_to_pascal(actor_name)
|
||||||
|
result_param := content_descriptor_to_parameter(method.result)!
|
||||||
return Function{
|
return Function{
|
||||||
name: texttools.name_fix_snake(method.name)
|
name: texttools.name_fix_snake(method.name)
|
||||||
receiver: code.new_param(v: 'mut actor ${actor_name_pascal}Actor')!
|
receiver: code.new_param(v: 'mut actor ${actor_name_pascal}Actor')!
|
||||||
result: Param{...content_descriptor_to_parameter(method.result)!, is_result: true}
|
result: Param {...result_param, typ: Result{result_param.typ}}
|
||||||
summary: method.summary
|
summary: method.summary
|
||||||
description: method.description
|
description: method.description
|
||||||
params: method.parameters.map(content_descriptor_to_parameter(it)!)
|
params: method.parameters.map(content_descriptor_to_parameter(it)!)
|
||||||
@@ -80,7 +81,7 @@ fn generate_base_object_new_body(method ActorMethod) !string {
|
|||||||
fn generate_base_object_get_body(method ActorMethod) !string {
|
fn generate_base_object_get_body(method ActorMethod) !string {
|
||||||
parameter := content_descriptor_to_parameter(method.parameters[0])!
|
parameter := content_descriptor_to_parameter(method.parameters[0])!
|
||||||
result := content_descriptor_to_parameter(method.result)!
|
result := content_descriptor_to_parameter(method.result)!
|
||||||
return 'return actor.osis.get[${result.typ.vgen()}](${parameter.name})!'
|
return 'return actor.osis.get[${result.typ.vgen()}](${texttools.name_fix_snake(parameter.name)})!'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_base_object_set_body(method ActorMethod) !string {
|
fn generate_base_object_set_body(method ActorMethod) !string {
|
||||||
@@ -90,10 +91,12 @@ fn generate_base_object_set_body(method ActorMethod) !string {
|
|||||||
|
|
||||||
fn generate_base_object_delete_body(method ActorMethod) !string {
|
fn generate_base_object_delete_body(method ActorMethod) !string {
|
||||||
parameter := content_descriptor_to_parameter(method.parameters[0])!
|
parameter := content_descriptor_to_parameter(method.parameters[0])!
|
||||||
return 'return actor.osis.delete(${parameter.name})!'
|
return 'actor.osis.delete(${texttools.name_fix_snake(parameter.name)})!'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_base_object_list_body(method ActorMethod) !string {
|
fn generate_base_object_list_body(method ActorMethod) !string {
|
||||||
result := content_descriptor_to_parameter(method.result)!
|
result := content_descriptor_to_parameter(method.result)!
|
||||||
return 'return actor.osis.list[${result.typ.vgen()}]()!'
|
|
||||||
|
base_object_type := (result.typ as Array).typ
|
||||||
|
return 'return actor.osis.list[${base_object_type.symbol()}]()!'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
module generator
|
module generator
|
||||||
|
|
||||||
import freeflowuniverse.herolib.baobab.specification {BaseObject}
|
import freeflowuniverse.herolib.baobab.specification {BaseObject}
|
||||||
import freeflowuniverse.herolib.core.code { VFile, CodeItem, Function, Import, Param, Param, Struct, StructField, Type }
|
import freeflowuniverse.herolib.core.code { type_from_symbol, VFile, CodeItem, Function, Import, Param, Param, Struct, StructField, Type }
|
||||||
import freeflowuniverse.herolib.core.texttools
|
import freeflowuniverse.herolib.core.texttools
|
||||||
|
|
||||||
const id_param = Param{
|
const id_param = Param{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: Type{
|
typ: type_from_symbol('u32')
|
||||||
symbol: 'u32'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn generate_object_code(actor Struct, object BaseObject) VFile {
|
// pub fn generate_object_code(actor Struct, object BaseObject) VFile {
|
||||||
@@ -47,366 +45,362 @@ const id_param = Param{
|
|||||||
// return file
|
// return file
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_get_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
get_method := Function{
|
|
||||||
name: 'get_${object_name}'
|
|
||||||
description: 'gets the ${object_name} with the given object id'
|
|
||||||
receiver: Param{
|
|
||||||
mutable: true
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params: [generator.id_param]
|
|
||||||
result: Param{
|
|
||||||
typ: Type{
|
|
||||||
symbol: object.structure.name
|
|
||||||
}
|
|
||||||
is_result: true
|
|
||||||
}
|
|
||||||
body: 'return actor.backend.get[${object_type}](id)!'
|
|
||||||
}
|
|
||||||
return get_method
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_set_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
param_getters := generate_param_getters(
|
|
||||||
structure: object.structure
|
|
||||||
prefix: ''
|
|
||||||
only_mutable: true
|
|
||||||
)
|
|
||||||
body := 'actor.backend.set[${object_type}](${object_name})!'
|
|
||||||
get_method := Function{
|
|
||||||
name: 'set_${object_name}'
|
|
||||||
description: 'updates the ${object.structure.name} with the given object id'
|
|
||||||
receiver: Param{
|
|
||||||
mutable: true
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params: [
|
|
||||||
Param{
|
|
||||||
name: object_name
|
|
||||||
typ: Type{
|
|
||||||
symbol: object_type
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
result: Param{
|
|
||||||
is_result: true
|
|
||||||
}
|
|
||||||
body: body
|
|
||||||
}
|
|
||||||
return get_method
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_delete_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
body := 'actor.backend.delete[${object_type}](id)!'
|
|
||||||
get_method := Function{
|
|
||||||
name: 'delete_${object_name}'
|
|
||||||
description: 'deletes the ${object.structure.name} with the given object id'
|
|
||||||
receiver: Param{
|
|
||||||
mutable: true
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params: [generator.id_param]
|
|
||||||
result: Param{
|
|
||||||
is_result: true
|
|
||||||
}
|
|
||||||
body: body
|
|
||||||
}
|
|
||||||
return get_method
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_new_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
param_getters := generate_param_getters(
|
|
||||||
structure: object.structure
|
|
||||||
prefix: ''
|
|
||||||
only_mutable: false
|
|
||||||
)
|
|
||||||
body := 'return actor.backend.new[${object_type}](${object_name})!'
|
|
||||||
new_method := Function{
|
|
||||||
name: 'new_${object_name}'
|
|
||||||
description: 'news the ${object.structure.name} with the given object id'
|
|
||||||
receiver: Param{
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
mutable: true
|
|
||||||
}
|
|
||||||
params: [
|
|
||||||
Param{
|
|
||||||
name: object_name
|
|
||||||
typ: Type{
|
|
||||||
symbol: object_type
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
result: Param{
|
|
||||||
is_result: true
|
|
||||||
typ: Type{
|
|
||||||
symbol: 'u32'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
body: body
|
|
||||||
}
|
|
||||||
return new_method
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_list_result_struct(actor Struct, object BaseObject) Struct {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
return Struct{
|
|
||||||
name: '${object_type}List'
|
|
||||||
is_pub: true
|
|
||||||
fields: [
|
|
||||||
StructField{
|
|
||||||
name: 'items'
|
|
||||||
typ: Type{
|
|
||||||
symbol: '[]${object_type}'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_list_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
list_struct := Struct{
|
|
||||||
name: '${object_type}List'
|
|
||||||
fields: [
|
|
||||||
StructField{
|
|
||||||
name: 'items'
|
|
||||||
typ: Type{
|
|
||||||
symbol: '[]${object_type}'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
param_getters := generate_param_getters(
|
|
||||||
structure: object.structure
|
|
||||||
prefix: ''
|
|
||||||
only_mutable: false
|
|
||||||
)
|
|
||||||
body := 'return ${object_type}List{items:actor.backend.list[${object_type}]()!}'
|
|
||||||
|
|
||||||
result_struct := generate_list_result_struct(actor, object)
|
|
||||||
mut result := Param{}
|
|
||||||
result.typ.symbol = result_struct.name
|
|
||||||
result.is_result = true
|
|
||||||
new_method := Function{
|
|
||||||
name: 'list_${object_name}'
|
|
||||||
description: 'lists all of the ${object_name} objects'
|
|
||||||
receiver: Param{
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
mutable: true
|
|
||||||
}
|
|
||||||
params: []
|
|
||||||
result: result
|
|
||||||
body: body
|
|
||||||
}
|
|
||||||
return new_method
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_filter_params(actor Struct, object BaseObject) []Struct {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
return [
|
|
||||||
Struct{
|
|
||||||
name: 'Filter${object_type}Params'
|
|
||||||
fields: [
|
|
||||||
StructField{
|
|
||||||
name: 'filter'
|
|
||||||
typ: Type{
|
|
||||||
symbol: '${object_type}Filter'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
StructField{
|
|
||||||
name: 'params'
|
|
||||||
typ: Type{
|
|
||||||
symbol: 'FilterParams'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
Struct{
|
|
||||||
name: '${object_type}Filter'
|
|
||||||
fields: object.structure.fields.filter(it.attrs.any(it.name == 'index'))
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate_object_methods generates CRUD actor methods for a provided structure
|
|
||||||
fn generate_filter_method(actor Struct, object BaseObject) Function {
|
|
||||||
object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
|
||||||
object_type := object.structure.name
|
|
||||||
|
|
||||||
param_getters := generate_param_getters(
|
|
||||||
structure: object.structure
|
|
||||||
prefix: ''
|
|
||||||
only_mutable: false
|
|
||||||
)
|
|
||||||
params_type := 'Filter${object_type}Params'
|
|
||||||
body := 'return actor.backend.filter[${object_type}, ${object_type}Filter](filter.filter, filter.params)!'
|
|
||||||
return Function{
|
|
||||||
name: 'filter_${object_name}'
|
|
||||||
description: 'lists all of the ${object_name} objects'
|
|
||||||
receiver: Param{
|
|
||||||
name: 'actor'
|
|
||||||
typ: Type{
|
|
||||||
symbol: actor.name
|
|
||||||
}
|
|
||||||
mutable: true
|
|
||||||
}
|
|
||||||
params: [
|
|
||||||
Param{
|
|
||||||
name: 'filter'
|
|
||||||
typ: Type{
|
|
||||||
symbol: params_type
|
|
||||||
}
|
|
||||||
},
|
|
||||||
]
|
|
||||||
result: Param{
|
|
||||||
typ: Type{
|
|
||||||
symbol: '[]${object_type}'
|
|
||||||
}
|
|
||||||
is_result: true
|
|
||||||
}
|
|
||||||
body: body
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// // generate_object_methods generates CRUD actor methods for a provided structure
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
// fn generate_object_methods(actor Struct, object BaseObject) []Function {
|
// fn generate_get_method(actor Struct, object BaseObject) Function {
|
||||||
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
// object_type := object.structure.name
|
// object_type := object.structure.name
|
||||||
|
|
||||||
// mut funcs := []Function{}
|
// get_method := Function{
|
||||||
// for method in object.methods {
|
// name: 'get_${object_name}'
|
||||||
// mut params := [Param{
|
// description: 'gets the ${object_name} with the given object id'
|
||||||
// name: 'id'
|
// receiver: Param{
|
||||||
|
// mutable: true
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: type_from_symbol(actor.name)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// params: [generator.id_param]
|
||||||
|
// result: Param{
|
||||||
|
// typ: type_from_symbol(object.structure.name)
|
||||||
|
// is_result: true
|
||||||
|
// }
|
||||||
|
// body: 'return actor.backend.get[${object_type}](id)!'
|
||||||
|
// }
|
||||||
|
// return get_method
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
|
// fn generate_set_method(actor Struct, object BaseObject) Function {
|
||||||
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
|
// object_type := object.structure.name
|
||||||
|
|
||||||
|
// param_getters := generate_param_getters(
|
||||||
|
// structure: object.structure
|
||||||
|
// prefix: ''
|
||||||
|
// only_mutable: true
|
||||||
|
// )
|
||||||
|
// body := 'actor.backend.set[${object_type}](${object_name})!'
|
||||||
|
// get_method := Function{
|
||||||
|
// name: 'set_${object_name}'
|
||||||
|
// description: 'updates the ${object.structure.name} with the given object id'
|
||||||
|
// receiver: Param{
|
||||||
|
// mutable: true
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: type_from_symbol(actor.name)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// params: [
|
||||||
|
// Param{
|
||||||
|
// name: object_name
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: object_type
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// result: Param{
|
||||||
|
// is_result: true
|
||||||
|
// }
|
||||||
|
// body: body
|
||||||
|
// }
|
||||||
|
// return get_method
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
|
// fn generate_delete_method(actor Struct, object BaseObject) Function {
|
||||||
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
|
// object_type := object.structure.name
|
||||||
|
|
||||||
|
// body := 'actor.backend.delete[${object_type}](id)!'
|
||||||
|
// get_method := Function{
|
||||||
|
// name: 'delete_${object_name}'
|
||||||
|
// description: 'deletes the ${object.structure.name} with the given object id'
|
||||||
|
// receiver: Param{
|
||||||
|
// mutable: true
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: actor.name
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// params: [generator.id_param]
|
||||||
|
// result: Param{
|
||||||
|
// is_result: true
|
||||||
|
// }
|
||||||
|
// body: body
|
||||||
|
// }
|
||||||
|
// return get_method
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
|
// fn generate_new_method(actor Struct, object BaseObject) Function {
|
||||||
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
|
// object_type := object.structure.name
|
||||||
|
|
||||||
|
// param_getters := generate_param_getters(
|
||||||
|
// structure: object.structure
|
||||||
|
// prefix: ''
|
||||||
|
// only_mutable: false
|
||||||
|
// )
|
||||||
|
// body := 'return actor.backend.new[${object_type}](${object_name})!'
|
||||||
|
// new_method := Function{
|
||||||
|
// name: 'new_${object_name}'
|
||||||
|
// description: 'news the ${object.structure.name} with the given object id'
|
||||||
|
// receiver: Param{
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: actor.name
|
||||||
|
// }
|
||||||
|
// mutable: true
|
||||||
|
// }
|
||||||
|
// params: [
|
||||||
|
// Param{
|
||||||
|
// name: object_name
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: object_type
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// result: Param{
|
||||||
|
// is_result: true
|
||||||
// typ: Type{
|
// typ: Type{
|
||||||
// symbol: 'u32'
|
// symbol: 'u32'
|
||||||
// }
|
// }
|
||||||
// }]
|
|
||||||
// params << method.params
|
|
||||||
// funcs << Function{
|
|
||||||
// name: method.name
|
|
||||||
// description: method.description
|
|
||||||
// receiver: Param{
|
|
||||||
// name: 'actor'
|
|
||||||
// typ: Type{
|
|
||||||
// symbol: actor.name
|
|
||||||
// }
|
|
||||||
// mutable: true
|
|
||||||
// }
|
|
||||||
// params: params
|
|
||||||
// result: method.result
|
|
||||||
// body: 'obj := actor.backend.get[${method.receiver.typ.symbol}](id)!
|
|
||||||
// obj.${method.name}(${method.params.map(it.name).join(',')})
|
|
||||||
// actor.backend.set[${method.receiver.typ.symbol}](obj)!
|
|
||||||
// '
|
|
||||||
// }
|
// }
|
||||||
|
// body: body
|
||||||
// }
|
// }
|
||||||
|
// return new_method
|
||||||
// return funcs
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@[params]
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
struct GenerateParamGetters {
|
// fn generate_list_result_struct(actor Struct, object BaseObject) Struct {
|
||||||
structure Struct
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
prefix string
|
// object_type := object.structure.name
|
||||||
only_mutable bool // if true generates param.get methods for only mutable struct fields. Used for updating.
|
// return Struct{
|
||||||
}
|
// name: '${object_type}List'
|
||||||
|
// is_pub: true
|
||||||
|
// fields: [
|
||||||
|
// StructField{
|
||||||
|
// name: 'items'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: '[]${object_type}'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
fn generate_param_getters(params GenerateParamGetters) []string {
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
mut param_getters := []string{}
|
// fn generate_list_method(actor Struct, object BaseObject) Function {
|
||||||
fields := if params.only_mutable {
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
params.structure.fields.filter(it.is_mut && it.is_pub)
|
// object_type := object.structure.name
|
||||||
} else {
|
|
||||||
params.structure.fields.filter(it.is_pub)
|
|
||||||
}
|
|
||||||
for field in fields {
|
|
||||||
if field.typ.symbol.starts_with_capital() {
|
|
||||||
subgetters := generate_param_getters(GenerateParamGetters{
|
|
||||||
...params
|
|
||||||
structure: field.structure
|
|
||||||
prefix: '${field.name}_'
|
|
||||||
})
|
|
||||||
// name of the tested object, used for param declaration
|
|
||||||
// ex: fruits []Fruit becomes fruit_name
|
|
||||||
nested_name := field.structure.name.to_lower()
|
|
||||||
if field.typ.is_map {
|
|
||||||
param_getters.insert(0, '${nested_name}_key := params.get(\'${nested_name}_key\')!')
|
|
||||||
param_getters << '${field.name}: {${nested_name}_key: ${field.structure.name}}{'
|
|
||||||
} else if field.typ.is_array {
|
|
||||||
param_getters << '${field.name}: [${field.structure.name}{'
|
|
||||||
} else {
|
|
||||||
param_getters << '${field.name}: ${field.structure.name}{'
|
|
||||||
}
|
|
||||||
param_getters << subgetters
|
|
||||||
param_getters << if field.typ.is_array { '}]' } else { '}' }
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
mut get_method := '${field.name}: params.get'
|
// list_struct := Struct{
|
||||||
if field.typ.symbol != 'string' {
|
// name: '${object_type}List'
|
||||||
// TODO: check if params method actually exists
|
// fields: [
|
||||||
'get_${field.typ.symbol}'
|
// StructField{
|
||||||
}
|
// name: 'items'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: '[]${object_type}'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
if field.default != '' {
|
// param_getters := generate_param_getters(
|
||||||
get_method += '_default'
|
// structure: object.structure
|
||||||
}
|
// prefix: ''
|
||||||
|
// only_mutable: false
|
||||||
|
// )
|
||||||
|
// body := 'return ${object_type}List{items:actor.backend.list[${object_type}]()!}'
|
||||||
|
|
||||||
|
// result_struct := generate_list_result_struct(actor, object)
|
||||||
|
// mut result := Param{}
|
||||||
|
// result.typ.symbol = result_struct.name
|
||||||
|
// result.is_result = true
|
||||||
|
// new_method := Function{
|
||||||
|
// name: 'list_${object_name}'
|
||||||
|
// description: 'lists all of the ${object_name} objects'
|
||||||
|
// receiver: Param{
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: actor.name
|
||||||
|
// }
|
||||||
|
// mutable: true
|
||||||
|
// }
|
||||||
|
// params: []
|
||||||
|
// result: result
|
||||||
|
// body: body
|
||||||
|
// }
|
||||||
|
// return new_method
|
||||||
|
// }
|
||||||
|
|
||||||
get_method = get_method + "('${params.prefix}${field.name}')!"
|
// fn generate_filter_params(actor Struct, object BaseObject) []Struct {
|
||||||
param_getters << get_method
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
}
|
// object_type := object.structure.name
|
||||||
return param_getters
|
|
||||||
}
|
|
||||||
|
|
||||||
@[params]
|
// return [
|
||||||
struct GetChildField {
|
// Struct{
|
||||||
parent Struct @[required]
|
// name: 'Filter${object_type}Params'
|
||||||
child Struct @[required]
|
// fields: [
|
||||||
}
|
// StructField{
|
||||||
|
// name: 'filter'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: '${object_type}Filter'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// StructField{
|
||||||
|
// name: 'params'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: 'FilterParams'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// Struct{
|
||||||
|
// name: '${object_type}Filter'
|
||||||
|
// fields: object.structure.fields.filter(it.attrs.any(it.name == 'index'))
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
|
||||||
fn get_child_field(params GetChildField) StructField {
|
// // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
fields := params.parent.fields.filter(it.typ.symbol == 'map[string]&${params.child.name}')
|
// fn generate_filter_method(actor Struct, object BaseObject) Function {
|
||||||
if fields.len != 1 {
|
// object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
panic('this should never happen')
|
// object_type := object.structure.name
|
||||||
}
|
|
||||||
return fields[0]
|
// param_getters := generate_param_getters(
|
||||||
}
|
// structure: object.structure
|
||||||
|
// prefix: ''
|
||||||
|
// only_mutable: false
|
||||||
|
// )
|
||||||
|
// params_type := 'Filter${object_type}Params'
|
||||||
|
// body := 'return actor.backend.filter[${object_type}, ${object_type}Filter](filter.filter, filter.params)!'
|
||||||
|
// return Function{
|
||||||
|
// name: 'filter_${object_name}'
|
||||||
|
// description: 'lists all of the ${object_name} objects'
|
||||||
|
// receiver: Param{
|
||||||
|
// name: 'actor'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: actor.name
|
||||||
|
// }
|
||||||
|
// mutable: true
|
||||||
|
// }
|
||||||
|
// params: [
|
||||||
|
// Param{
|
||||||
|
// name: 'filter'
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: params_type
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// ]
|
||||||
|
// result: Param{
|
||||||
|
// typ: Type{
|
||||||
|
// symbol: '[]${object_type}'
|
||||||
|
// }
|
||||||
|
// is_result: true
|
||||||
|
// }
|
||||||
|
// body: body
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // // generate_object_methods generates CRUD actor methods for a provided structure
|
||||||
|
// // fn generate_object_methods(actor Struct, object BaseObject) []Function {
|
||||||
|
// // object_name := texttools.name_fix_pascal_to_snake(object.structure.name)
|
||||||
|
// // object_type := object.structure.name
|
||||||
|
|
||||||
|
// // mut funcs := []Function{}
|
||||||
|
// // for method in object.methods {
|
||||||
|
// // mut params := [Param{
|
||||||
|
// // name: 'id'
|
||||||
|
// // typ: Type{
|
||||||
|
// // symbol: 'u32'
|
||||||
|
// // }
|
||||||
|
// // }]
|
||||||
|
// // params << method.params
|
||||||
|
// // funcs << Function{
|
||||||
|
// // name: method.name
|
||||||
|
// // description: method.description
|
||||||
|
// // receiver: Param{
|
||||||
|
// // name: 'actor'
|
||||||
|
// // typ: Type{
|
||||||
|
// // symbol: actor.name
|
||||||
|
// // }
|
||||||
|
// // mutable: true
|
||||||
|
// // }
|
||||||
|
// // params: params
|
||||||
|
// // result: method.result
|
||||||
|
// // body: 'obj := actor.backend.get[${method.receiver.typ.symbol}](id)!
|
||||||
|
// // obj.${method.name}(${method.params.map(it.name).join(',')})
|
||||||
|
// // actor.backend.set[${method.receiver.typ.symbol}](obj)!
|
||||||
|
// // '
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // return funcs
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// @[params]
|
||||||
|
// struct GenerateParamGetters {
|
||||||
|
// structure Struct
|
||||||
|
// prefix string
|
||||||
|
// only_mutable bool // if true generates param.get methods for only mutable struct fields. Used for updating.
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn generate_param_getters(params GenerateParamGetters) []string {
|
||||||
|
// mut param_getters := []string{}
|
||||||
|
// fields := if params.only_mutable {
|
||||||
|
// params.structure.fields.filter(it.is_mut && it.is_pub)
|
||||||
|
// } else {
|
||||||
|
// params.structure.fields.filter(it.is_pub)
|
||||||
|
// }
|
||||||
|
// for field in fields {
|
||||||
|
// if field.typ.symbol.starts_with_capital() {
|
||||||
|
// subgetters := generate_param_getters(GenerateParamGetters{
|
||||||
|
// ...params
|
||||||
|
// structure: field.structure
|
||||||
|
// prefix: '${field.name}_'
|
||||||
|
// })
|
||||||
|
// // name of the tested object, used for param declaration
|
||||||
|
// // ex: fruits []Fruit becomes fruit_name
|
||||||
|
// nested_name := field.structure.name.to_lower()
|
||||||
|
// if field.typ.is_map {
|
||||||
|
// param_getters.insert(0, '${nested_name}_key := params.get(\'${nested_name}_key\')!')
|
||||||
|
// param_getters << '${field.name}: {${nested_name}_key: ${field.structure.name}}{'
|
||||||
|
// } else if field.typ.is_array {
|
||||||
|
// param_getters << '${field.name}: [${field.structure.name}{'
|
||||||
|
// } else {
|
||||||
|
// param_getters << '${field.name}: ${field.structure.name}{'
|
||||||
|
// }
|
||||||
|
// param_getters << subgetters
|
||||||
|
// param_getters << if field.typ.is_array { '}]' } else { '}' }
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
|
||||||
|
// mut get_method := '${field.name}: params.get'
|
||||||
|
// if field.typ.symbol != 'string' {
|
||||||
|
// // TODO: check if params method actually exists
|
||||||
|
// 'get_${field.typ.symbol}'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if field.default != '' {
|
||||||
|
// get_method += '_default'
|
||||||
|
// }
|
||||||
|
|
||||||
|
// get_method = get_method + "('${params.prefix}${field.name}')!"
|
||||||
|
// param_getters << get_method
|
||||||
|
// }
|
||||||
|
// return param_getters
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @[params]
|
||||||
|
// struct GetChildField {
|
||||||
|
// parent Struct @[required]
|
||||||
|
// child Struct @[required]
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn get_child_field(params GetChildField) StructField {
|
||||||
|
// fields := params.parent.fields.filter(it.typ.symbol == 'map[string]&${params.child.name}')
|
||||||
|
// if fields.len != 1 {
|
||||||
|
// panic('this should never happen')
|
||||||
|
// }
|
||||||
|
// return fields[0]
|
||||||
|
// }
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ code_md := ''
|
|||||||
// describes the struct in markdown format
|
// describes the struct in markdown format
|
||||||
for struct in structs {
|
for struct in structs {
|
||||||
code_md += '# ${struct.name}'
|
code_md += '# ${struct.name}'
|
||||||
code_md += 'Type: ${struct.typ.symbol}'
|
code_md += 'Type: ${struct.typ.symbol()}'
|
||||||
code_md += '## Fields:'
|
code_md += '## Fields:'
|
||||||
for field in struct.fields {
|
for field in struct.fields {
|
||||||
code_md += '- ${field.name}'
|
code_md += '- ${field.name}'
|
||||||
|
|||||||
@@ -28,6 +28,66 @@ pub mut:
|
|||||||
struct_ Struct @[omitempty]
|
struct_ Struct @[omitempty]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type Type = Array | Object | Result | Integer | Alias | String
|
||||||
|
|
||||||
|
pub struct Integer {
|
||||||
|
bytes u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_from_symbol(symbol_ string) Type {
|
||||||
|
mut symbol := symbol_.trim_space()
|
||||||
|
if symbol.starts_with('[]') {
|
||||||
|
return Array{type_from_symbol(symbol.all_after('[]'))}
|
||||||
|
} else if symbol == 'int' {
|
||||||
|
return Integer{}
|
||||||
|
} else if symbol == 'string' {
|
||||||
|
return String{}
|
||||||
|
}
|
||||||
|
return Object{symbol}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (t Type) symbol() string {
|
||||||
|
return match t {
|
||||||
|
Array { '[]${t.typ.symbol()}' }
|
||||||
|
Object { t.name }
|
||||||
|
Result { '!${t.typ.symbol()}'}
|
||||||
|
Integer {'int'}
|
||||||
|
Alias {t.name}
|
||||||
|
String {'string'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct String {}
|
||||||
|
|
||||||
|
pub struct Array {
|
||||||
|
pub:
|
||||||
|
typ Type
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Object {
|
||||||
|
pub:
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Result {
|
||||||
|
pub:
|
||||||
|
typ Type
|
||||||
|
}
|
||||||
|
|
||||||
|
// // todo: maybe make 'is_' fields methods?
|
||||||
|
// pub struct Type {
|
||||||
|
// pub mut:
|
||||||
|
// is_reference bool @[str: skip]
|
||||||
|
// is_map bool @[str: skip]
|
||||||
|
// is_array bool
|
||||||
|
// is_mutable bool @[str: skip]
|
||||||
|
// is_shared bool @[str: skip]
|
||||||
|
// is_optional bool @[str: skip]
|
||||||
|
// is_result bool @[str: skip]
|
||||||
|
// symbol string
|
||||||
|
// mod string @[str: skip]
|
||||||
|
// }
|
||||||
|
|
||||||
@[params]
|
@[params]
|
||||||
pub struct Params{
|
pub struct Params{
|
||||||
pub:
|
pub:
|
||||||
@@ -39,16 +99,6 @@ pub fn new_param(params Params) !Param {
|
|||||||
return parse_param(params.v)!
|
return parse_param(params.v)!
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Result {
|
|
||||||
pub mut:
|
|
||||||
typ Type @[omitempty]
|
|
||||||
description string @[omitempty]
|
|
||||||
name string @[omitempty]
|
|
||||||
result bool @[omitempty] // whether is result type
|
|
||||||
optional bool @[omitempty] // whether is result type
|
|
||||||
structure Struct @[omitempty]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_function(code string) !Function {
|
pub fn new_function(code string) !Function {
|
||||||
// TODO: implement function from file line
|
// TODO: implement function from file line
|
||||||
return parse_function(code)!
|
return parse_function(code)!
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ pub fn parse_param(code_ string) !Param {
|
|||||||
if split.len == 1 {
|
if split.len == 1 {
|
||||||
// means anonymous param
|
// means anonymous param
|
||||||
return Param{
|
return Param{
|
||||||
typ: Type{
|
typ: type_from_symbol(split[0])
|
||||||
symbol: split[0]
|
|
||||||
}
|
|
||||||
mutable: is_mut
|
mutable: is_mut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,41 +85,11 @@ pub fn parse_param(code_ string) !Param {
|
|||||||
}
|
}
|
||||||
return Param{
|
return Param{
|
||||||
name: split[0]
|
name: split[0]
|
||||||
typ: Type{
|
typ: type_from_symbol(split[1])
|
||||||
symbol: split[1]
|
|
||||||
}
|
|
||||||
mutable: is_mut
|
mutable: is_mut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_result(code_ string) !Result {
|
|
||||||
code := code_.replace(' ', '').trim_space()
|
|
||||||
|
|
||||||
return Result{
|
|
||||||
result: code_.starts_with('!')
|
|
||||||
optional: code_.starts_with('?')
|
|
||||||
typ: Type{
|
|
||||||
symbol: code.trim('!?')
|
|
||||||
is_optional: code.starts_with('?')
|
|
||||||
is_result: code.starts_with('!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: maybe make 'is_' fields methods?
|
|
||||||
pub struct Type {
|
|
||||||
pub mut:
|
|
||||||
is_reference bool @[str: skip]
|
|
||||||
is_map bool @[str: skip]
|
|
||||||
is_array bool
|
|
||||||
is_mutable bool @[str: skip]
|
|
||||||
is_shared bool @[str: skip]
|
|
||||||
is_optional bool @[str: skip]
|
|
||||||
is_result bool @[str: skip]
|
|
||||||
symbol string
|
|
||||||
mod string @[str: skip]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Alias {
|
pub struct Alias {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ pub fn inflate_types(mut code []CodeItem) {
|
|||||||
pub fn inflate_struct_fields(code []CodeItem, mut struct_ CodeItem) {
|
pub fn inflate_struct_fields(code []CodeItem, mut struct_ CodeItem) {
|
||||||
for mut field in (struct_ as Struct).fields {
|
for mut field in (struct_ as Struct).fields {
|
||||||
// TODO: fix inflation for imported types
|
// TODO: fix inflation for imported types
|
||||||
if field.typ.symbol.starts_with_capital() {
|
if field.typ.symbol().starts_with_capital() {
|
||||||
field.structure = get_struct(
|
field.structure = get_struct(
|
||||||
code: code
|
code: code
|
||||||
name: field.typ.symbol
|
name: field.typ.symbol()
|
||||||
) or { continue }
|
) or { continue }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ pub:
|
|||||||
|
|
||||||
pub fn (func Function) generate_call(params GenerateCallParams) !string {
|
pub fn (func Function) generate_call(params GenerateCallParams) !string {
|
||||||
mut call := ''
|
mut call := ''
|
||||||
if func.result.typ.symbol != '' {
|
if func.result.typ.symbol() != '' {
|
||||||
call = 'result := '
|
call = 'result := '
|
||||||
}
|
}
|
||||||
call += if params.receiver != '' {
|
call += if params.receiver != '' {
|
||||||
@@ -79,12 +79,12 @@ pub struct GenerateValueParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (param Param) generate_value() !string {
|
pub fn (param Param) generate_value() !string {
|
||||||
if param.typ.symbol == 'string' {
|
if param.typ.symbol() == 'string' {
|
||||||
return "'mock_string_${rand.string(3)}'"
|
return "'mock_string_${rand.string(3)}'"
|
||||||
} else if param.typ.symbol == 'int' || param.typ.symbol == 'u32' {
|
} else if param.typ.symbol() == 'int' || param.typ.symbol() == 'u32' {
|
||||||
return '42'
|
return '42'
|
||||||
} else if param.typ.symbol[0].is_capital() {
|
} else if param.typ.symbol()[0].is_capital() {
|
||||||
return '${param.typ.symbol}{}'
|
return '${param.typ.symbol()}{}'
|
||||||
} else {
|
} else {
|
||||||
log.debug('mock values for types other than strings and ints are not yet supported')
|
log.debug('mock values for types other than strings and ints are not yet supported')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,21 +43,8 @@ pub fn (import_ Import) vgen() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: enfore that cant be both mutable and shared
|
// TODO: enfore that cant be both mutable and shared
|
||||||
pub fn (type_ Type) vgen() string {
|
pub fn (t Type) vgen() string {
|
||||||
mut type_str := ''
|
return t.symbol()
|
||||||
if type_.is_mutable {
|
|
||||||
type_str += 'mut '
|
|
||||||
} else if type_.is_shared {
|
|
||||||
type_str += 'shared '
|
|
||||||
}
|
|
||||||
|
|
||||||
if type_.is_optional {
|
|
||||||
type_str += '?'
|
|
||||||
} else if type_.is_result {
|
|
||||||
type_str += '!'
|
|
||||||
}
|
|
||||||
|
|
||||||
return '${type_str} ${type_.symbol}'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (field StructField) vgen() string {
|
pub fn (field StructField) vgen() string {
|
||||||
@@ -73,7 +60,7 @@ pub fn (field StructField) get_type_symbol() string {
|
|||||||
mut field_str := if field.structure.name != '' {
|
mut field_str := if field.structure.name != '' {
|
||||||
field.structure.get_type_symbol()
|
field.structure.get_type_symbol()
|
||||||
} else {
|
} else {
|
||||||
field.typ.symbol
|
field.typ.symbol()
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.is_ref {
|
if field.is_ref {
|
||||||
@@ -111,12 +98,10 @@ pub fn vgen_generics(generics map[string]string) string {
|
|||||||
pub fn (function Function) vgen(options WriteOptions) string {
|
pub fn (function Function) vgen(options WriteOptions) string {
|
||||||
mut params_ := function.params.map(Param{
|
mut params_ := function.params.map(Param{
|
||||||
...it
|
...it
|
||||||
typ: Type{
|
typ: if it.struct_.name != '' {
|
||||||
symbol: if it.struct_.name != '' {
|
type_from_symbol(it.struct_.name)
|
||||||
it.struct_.name
|
} else {
|
||||||
} else {
|
it.typ
|
||||||
it.typ.symbol
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -129,17 +114,13 @@ pub fn (function Function) vgen(options WriteOptions) string {
|
|||||||
fields: optionals.map(StructField{
|
fields: optionals.map(StructField{
|
||||||
name: it.name
|
name: it.name
|
||||||
description: it.description
|
description: it.description
|
||||||
typ: Type{
|
typ: it.typ
|
||||||
symbol: it.typ.symbol
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if optionals.len > 0 {
|
if optionals.len > 0 {
|
||||||
params_ << Param{
|
params_ << Param{
|
||||||
name: 'options'
|
name: 'options'
|
||||||
typ: Type{
|
typ: type_from_symbol(options_struct.name)
|
||||||
symbol: options_struct.name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,22 +153,9 @@ pub fn (function Function) vgen(options WriteOptions) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn (param Param) vgen() string {
|
pub fn (param Param) vgen() string {
|
||||||
// if param.name == '' {
|
sym := param.typ.symbol()
|
||||||
// return ''
|
|
||||||
// }
|
|
||||||
sym := if param.struct_.name != '' {
|
|
||||||
param.struct_.get_type_symbol()
|
|
||||||
} else {
|
|
||||||
param.typ.symbol
|
|
||||||
}
|
|
||||||
param_name := texttools.name_fix_snake(param.name)
|
param_name := texttools.name_fix_snake(param.name)
|
||||||
mut vstr := '${param_name} ${sym}'
|
mut vstr := '${param_name} ${sym}'
|
||||||
if param.typ.is_reference {
|
|
||||||
vstr = '&${vstr}'
|
|
||||||
}
|
|
||||||
if param.is_result {
|
|
||||||
vstr = '!${vstr}'
|
|
||||||
}
|
|
||||||
if param.mutable {
|
if param.mutable {
|
||||||
vstr = 'mut ${vstr}'
|
vstr = 'mut ${vstr}'
|
||||||
}
|
}
|
||||||
@@ -196,19 +164,6 @@ pub fn (param Param) vgen() string {
|
|||||||
|
|
||||||
// vgen_function generates a function statement for a function
|
// vgen_function generates a function statement for a function
|
||||||
pub fn (struct_ Struct) vgen() string {
|
pub fn (struct_ Struct) vgen() string {
|
||||||
gen := VGenerator{false}
|
|
||||||
return gen.generate_struct(struct_) or { panic(err) }
|
|
||||||
// mut struct_str := $tmpl('templates/struct/struct.v.template')
|
|
||||||
// return struct_str
|
|
||||||
// result := os.execute_opt('echo "${struct_str.replace('$', '\$')}" | v fmt') or {panic(err)}
|
|
||||||
// return result.output
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct VGenerator {
|
|
||||||
format bool
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (gen VGenerator) generate_struct(struct_ Struct) !string {
|
|
||||||
name := if struct_.generics.len > 0 {
|
name := if struct_.generics.len > 0 {
|
||||||
'${struct_.name}${vgen_generics(struct_.generics)}'
|
'${struct_.name}${vgen_generics(struct_.generics)}'
|
||||||
} else {
|
} else {
|
||||||
@@ -221,13 +176,13 @@ pub fn (gen VGenerator) generate_struct(struct_ Struct) !string {
|
|||||||
''
|
''
|
||||||
}
|
}
|
||||||
|
|
||||||
priv_fields := struct_.fields.filter(!it.is_mut && !it.is_pub).map(gen.generate_struct_field(it))
|
priv_fields := struct_.fields.filter(!it.is_mut && !it.is_pub).map(generate_struct_field(it))
|
||||||
pub_fields := struct_.fields.filter(!it.is_mut && it.is_pub).map(gen.generate_struct_field(it))
|
pub_fields := struct_.fields.filter(!it.is_mut && it.is_pub).map(generate_struct_field(it))
|
||||||
mut_fields := struct_.fields.filter(it.is_mut && !it.is_pub).map(gen.generate_struct_field(it))
|
mut_fields := struct_.fields.filter(it.is_mut && !it.is_pub).map(generate_struct_field(it))
|
||||||
pub_mut_fields := struct_.fields.filter(it.is_mut && it.is_pub).map(gen.generate_struct_field(it))
|
pub_mut_fields := struct_.fields.filter(it.is_mut && it.is_pub).map(generate_struct_field(it))
|
||||||
|
|
||||||
mut struct_str := $tmpl('templates/struct/struct.v.template')
|
mut struct_str := $tmpl('templates/struct/struct.v.template')
|
||||||
if gen.format {
|
if false {
|
||||||
result := os.execute_opt('echo "${struct_str.replace('$', '\$')}" | v fmt') or {
|
result := os.execute_opt('echo "${struct_str.replace('$', '\$')}" | v fmt') or {
|
||||||
log.debug(struct_str)
|
log.debug(struct_str)
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -235,9 +190,13 @@ pub fn (gen VGenerator) generate_struct(struct_ Struct) !string {
|
|||||||
return result.output
|
return result.output
|
||||||
}
|
}
|
||||||
return struct_str
|
return struct_str
|
||||||
|
// mut struct_str := $tmpl('templates/struct/struct.v.template')
|
||||||
|
// return struct_str
|
||||||
|
// result := os.execute_opt('echo "${struct_str.replace('$', '\$')}" | v fmt') or {panic(err)}
|
||||||
|
// return result.output
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (gen VGenerator) generate_struct_field(field StructField) string {
|
pub fn generate_struct_field(field StructField) string {
|
||||||
symbol := field.get_type_symbol()
|
symbol := field.get_type_symbol()
|
||||||
mut vstr := '${field.name} ${symbol}'
|
mut vstr := '${field.name} ${symbol}'
|
||||||
if field.description != '' {
|
if field.description != '' {
|
||||||
@@ -250,29 +209,6 @@ pub fn (custom CustomCode) vgen() string {
|
|||||||
return custom.text
|
return custom.text
|
||||||
}
|
}
|
||||||
|
|
||||||
// vgen_function generates a function statement for a function
|
|
||||||
pub fn (result Result) vgen() string {
|
|
||||||
result_type := if result.structure.name != '' {
|
|
||||||
result.structure.get_type_symbol()
|
|
||||||
} else if result.typ.symbol == 'void' {
|
|
||||||
''
|
|
||||||
} else {
|
|
||||||
if result.typ.is_array {
|
|
||||||
'[]${result.typ.symbol}'
|
|
||||||
} else {
|
|
||||||
result.typ.symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str := if result.result {
|
|
||||||
'!'
|
|
||||||
} else if result.typ.is_result {
|
|
||||||
'!'
|
|
||||||
} else {
|
|
||||||
''
|
|
||||||
}
|
|
||||||
return '${str}${result_type}'
|
|
||||||
}
|
|
||||||
|
|
||||||
@[params]
|
@[params]
|
||||||
pub struct WriteOptions {
|
pub struct WriteOptions {
|
||||||
pub:
|
pub:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module codegen
|
module codegen
|
||||||
|
|
||||||
import freeflowuniverse.herolib.core.code { Alias, Attribute, CodeItem, Struct, StructField, Type }
|
import freeflowuniverse.herolib.core.code { Alias, Attribute, CodeItem, Struct, StructField, Type, type_from_symbol, Object, Array}
|
||||||
import freeflowuniverse.herolib.schemas.jsonschema { Schema, SchemaRef, Reference }
|
import freeflowuniverse.herolib.schemas.jsonschema { Schema, SchemaRef, Reference }
|
||||||
|
|
||||||
const vtypes = {
|
const vtypes = {
|
||||||
@@ -35,7 +35,7 @@ pub fn schema_to_structs(schema Schema) ![]string {
|
|||||||
typesymbol = ref_to_symbol(ref)
|
typesymbol = ref_to_symbol(ref)
|
||||||
} else {
|
} else {
|
||||||
property = property_ as Schema
|
property = property_ as Schema
|
||||||
typesymbol = schema_to_type(property)!
|
typesymbol = schema_to_type(property)!.symbol()
|
||||||
// recursively encode property if object
|
// recursively encode property if object
|
||||||
// todo: handle duplicates
|
// todo: handle duplicates
|
||||||
if property.typ == 'object' {
|
if property.typ == 'object' {
|
||||||
@@ -54,34 +54,36 @@ pub fn schema_to_structs(schema Schema) ![]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// schema_to_type generates a typesymbol for the schema
|
// schema_to_type generates a typesymbol for the schema
|
||||||
pub fn schema_to_type(schema Schema) !string {
|
pub fn schema_to_type(schema Schema) !Type {
|
||||||
mut property_str := ''
|
|
||||||
if schema.typ == 'null' {
|
if schema.typ == 'null' {
|
||||||
return ''
|
Type{}
|
||||||
}
|
}
|
||||||
if schema.typ == 'object' {
|
mut property_str := ''
|
||||||
if schema.title == '' {
|
return match schema.typ {
|
||||||
return error('Object schemas must define a title.')
|
'object' {
|
||||||
}
|
if schema.title == '' {
|
||||||
// todo: enforce uppercase
|
return error('Object schemas must define a title.')
|
||||||
property_str = schema.title
|
}
|
||||||
} else if schema.typ == 'array' {
|
Object{schema.title}
|
||||||
|
}
|
||||||
|
'array' {
|
||||||
// todo: handle multiple item schemas
|
// todo: handle multiple item schemas
|
||||||
if schema.items is SchemaRef {
|
if schema.items is []SchemaRef {
|
||||||
// items := schema.items as SchemaRef
|
return error('items of type []SchemaRef not implemented')
|
||||||
if schema.items is Schema {
|
}
|
||||||
items_schema := schema.items as Schema
|
Array {
|
||||||
property_str = '[]${items_schema.typ}'
|
typ: schemaref_to_type(schema.items as SchemaRef)!
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if schema.typ in vtypes.keys() {
|
||||||
|
type_from_symbol(vtypes[schema.typ])
|
||||||
|
} else if schema.title != '' {
|
||||||
|
type_from_symbol(schema.title)
|
||||||
|
} else {
|
||||||
|
return error('unknown type `${schema.typ}` ')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if schema.typ in vtypes.keys() {
|
}
|
||||||
property_str = vtypes[schema.typ]
|
|
||||||
} else if schema.title != '' {
|
|
||||||
property_str = schema.title
|
|
||||||
} else {
|
|
||||||
return error('unknown type `${schema.typ}` ')
|
|
||||||
}
|
|
||||||
return property_str
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schema_to_code(schema Schema) !CodeItem {
|
pub fn schema_to_code(schema Schema) !CodeItem {
|
||||||
@@ -91,9 +93,7 @@ pub fn schema_to_code(schema Schema) !CodeItem {
|
|||||||
if schema.typ in vtypes {
|
if schema.typ in vtypes {
|
||||||
return Alias{
|
return Alias{
|
||||||
name: schema.title
|
name: schema.title
|
||||||
typ: Type{
|
typ: type_from_symbol(vtypes[schema.typ])
|
||||||
symbol: vtypes[schema.typ]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if schema.typ == 'array' {
|
if schema.typ == 'array' {
|
||||||
@@ -102,17 +102,13 @@ pub fn schema_to_code(schema Schema) !CodeItem {
|
|||||||
items_schema := schema.items as Schema
|
items_schema := schema.items as Schema
|
||||||
return Alias{
|
return Alias{
|
||||||
name: schema.title
|
name: schema.title
|
||||||
typ: Type{
|
typ: type_from_symbol('[]${items_schema.typ}')
|
||||||
symbol: '[]${items_schema.typ}'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if schema.items is Reference {
|
} else if schema.items is Reference {
|
||||||
items_ref := schema.items as Reference
|
items_ref := schema.items as Reference
|
||||||
return Alias{
|
return Alias{
|
||||||
name: schema.title
|
name: schema.title
|
||||||
typ: Type{
|
typ: type_from_symbol('[]${ref_to_symbol(items_ref)}')
|
||||||
symbol: '[]${ref_to_symbol(items_ref)}'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,9 +140,7 @@ pub fn ref_to_field(schema_ref SchemaRef, name string) !StructField {
|
|||||||
if schema_ref is Reference {
|
if schema_ref is Reference {
|
||||||
return StructField{
|
return StructField{
|
||||||
name: name
|
name: name
|
||||||
typ: Type{
|
typ: type_from_symbol(ref_to_symbol(schema_ref))
|
||||||
symbol: ref_to_symbol(schema_ref)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if schema_ref is Schema {
|
} else if schema_ref is Schema {
|
||||||
mut field := StructField{
|
mut field := StructField{
|
||||||
@@ -158,7 +152,7 @@ pub fn ref_to_field(schema_ref SchemaRef, name string) !StructField {
|
|||||||
field.anon_struct = schema_to_struct(schema_ref as Schema)!
|
field.anon_struct = schema_to_struct(schema_ref as Schema)!
|
||||||
return field
|
return field
|
||||||
} else if schema_ref.typ in vtypes {
|
} else if schema_ref.typ in vtypes {
|
||||||
field.typ.symbol = vtypes[schema_ref.typ]
|
field.typ = type_from_symbol(vtypes[schema_ref.typ])
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
return error('Schema type ${schema_ref.typ} not supported for code generation')
|
return error('Schema type ${schema_ref.typ} not supported for code generation')
|
||||||
@@ -170,9 +164,7 @@ pub fn schemaref_to_type(schema_ref SchemaRef) !Type {
|
|||||||
return if schema_ref is Reference {
|
return if schema_ref is Reference {
|
||||||
ref_to_type_from_reference(schema_ref as Reference)
|
ref_to_type_from_reference(schema_ref as Reference)
|
||||||
} else {
|
} else {
|
||||||
Type{
|
schema_to_type(schema_ref as Schema)!
|
||||||
symbol: schema_to_type(schema_ref as Schema)!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +173,5 @@ pub fn ref_to_symbol(reference Reference) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn ref_to_type_from_reference(reference Reference) Type {
|
pub fn ref_to_type_from_reference(reference Reference) Type {
|
||||||
return Type{
|
return type_from_symbol(ref_to_symbol(reference))
|
||||||
symbol: ref_to_symbol(reference)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ import freeflowuniverse.herolib.schemas.jsonschema { SchemaRef, Schema, Referenc
|
|||||||
pub fn sumtype_to_schema(sumtype code.Sumtype) SchemaRef {
|
pub fn sumtype_to_schema(sumtype code.Sumtype) SchemaRef {
|
||||||
mut one_of := []SchemaRef{}
|
mut one_of := []SchemaRef{}
|
||||||
for type_ in sumtype.types {
|
for type_ in sumtype.types {
|
||||||
property_schema := typesymbol_to_schema(type_.symbol)
|
property_schema := typesymbol_to_schema(type_.symbol())
|
||||||
one_of << property_schema
|
one_of << property_schema
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ pub fn struct_to_schema(struct_ Struct) SchemaRef {
|
|||||||
mut properties := map[string]SchemaRef{}
|
mut properties := map[string]SchemaRef{}
|
||||||
for field in struct_.fields {
|
for field in struct_.fields {
|
||||||
mut property_schema := SchemaRef(Schema{})
|
mut property_schema := SchemaRef(Schema{})
|
||||||
if field.typ.symbol.starts_with('_VAnonStruct') {
|
if field.typ.symbol().starts_with('_VAnonStruct') {
|
||||||
property_schema = struct_to_schema(field.anon_struct)
|
property_schema = struct_to_schema(field.anon_struct)
|
||||||
} else {
|
} else {
|
||||||
property_schema = type_to_schema(field.typ)
|
property_schema = type_to_schema(field.typ)
|
||||||
@@ -57,14 +57,7 @@ pub fn param_to_schema(param Param) SchemaRef {
|
|||||||
if param.struct_ != Struct{} {
|
if param.struct_ != Struct{} {
|
||||||
return struct_to_schema(param.struct_)
|
return struct_to_schema(param.struct_)
|
||||||
}
|
}
|
||||||
return typesymbol_to_schema(param.typ.symbol)
|
return typesymbol_to_schema(param.typ.symbol())
|
||||||
}
|
|
||||||
|
|
||||||
pub fn result_to_schema(result Result) SchemaRef {
|
|
||||||
if result.structure != Struct{} {
|
|
||||||
return struct_to_schema(result.structure)
|
|
||||||
}
|
|
||||||
return typesymbol_to_schema(result.typ.symbol)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// typesymbol_to_schema receives a typesymbol, if the typesymbol belongs to a user defined struct
|
// typesymbol_to_schema receives a typesymbol, if the typesymbol belongs to a user defined struct
|
||||||
@@ -172,12 +165,12 @@ pub fn typesymbol_to_schema(symbol_ string) SchemaRef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_to_schema(typ Type) SchemaRef {
|
pub fn type_to_schema(typ Type) SchemaRef {
|
||||||
mut symbol := typ.symbol.trim_string_left('!').trim_string_left('?')
|
mut symbol := typ.symbol().trim_string_left('!').trim_string_left('?')
|
||||||
if symbol == '' {
|
if symbol == '' {
|
||||||
return SchemaRef(Schema{
|
return SchemaRef(Schema{
|
||||||
typ: 'null'
|
typ: 'null'
|
||||||
})
|
})
|
||||||
} else if symbol.starts_with('[]') || typ.is_array {
|
} else if symbol.starts_with('[]') {
|
||||||
mut array_type := symbol.trim_string_left('[]')
|
mut array_type := symbol.trim_string_left('[]')
|
||||||
return SchemaRef(Schema{
|
return SchemaRef(Schema{
|
||||||
typ: 'array'
|
typ: 'array'
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ pub fn generate_handler_test_file(o OpenRPC, receiver Struct, method_map map[str
|
|||||||
if method.params.len == 0 {
|
if method.params.len == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if method.params[0].typ.symbol[0].is_capital() {
|
if method.params[0].typ.symbol()[0].is_capital() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
method_handle_test := Function{
|
method_handle_test := Function{
|
||||||
@@ -64,7 +64,7 @@ pub fn generate_handler_test_file(o OpenRPC, receiver Struct, method_map map[str
|
|||||||
is_result: true
|
is_result: true
|
||||||
}
|
}
|
||||||
body: "mut handler := ${receiver.name}Handler {${handler_name}.get(name: actor_name)!}
|
body: "mut handler := ${receiver.name}Handler {${handler_name}.get(name: actor_name)!}
|
||||||
request := new_jsonrpcrequest[${method.params[0].typ.symbol}]('${method.name}', ${get_mock_value(method.params[0].typ.symbol)!})
|
request := new_jsonrpcrequest[${method.params[0].typ.symbol()}]('${method.name}', ${get_mock_value(method.params[0].typ.symbol())!})
|
||||||
response_json := handler.handle(request.to_json())!"
|
response_json := handler.handle(request.to_json())!"
|
||||||
}
|
}
|
||||||
handle_tests << method_handle_test
|
handle_tests << method_handle_test
|
||||||
|
|||||||
Reference in New Issue
Block a user