Files
herolib/lib/baobab/generator/generate_clients.v
2025-02-12 03:37:22 +03:00

133 lines
3.3 KiB
V

module generator
import freeflowuniverse.herolib.core.code { Param, Folder, IFile, VFile, CodeItem, File, Function, Import, Module, Struct, CustomCode, Result }
import freeflowuniverse.herolib.core.texttools
import freeflowuniverse.herolib.schemas.jsonschema.codegen as jsonschema_codegen {schemaref_to_type}
import freeflowuniverse.herolib.schemas.openrpc.codegen {content_descriptor_to_parameter}
import freeflowuniverse.herolib.baobab.specification {ActorMethod, ActorSpecification}
pub fn generate_client_file(spec ActorSpecification) !VFile {
actor_name_snake := texttools.snake_case(spec.name)
actor_name_pascal := texttools.snake_case_to_pascal(spec.name)
mut items := []CodeItem{}
items << CustomCode {'
pub struct Client {
stage.Client
}
fn new_client(config stage.ActorConfig) !Client {
return Client {
Client: stage.new_client(config)!
}
}'}
for method in spec.methods {
items << generate_client_method(method)!
}
return VFile {
imports: [
Import{
mod: 'freeflowuniverse.herolib.baobab.stage'
},
Import{
mod: 'freeflowuniverse.herolib.core.redisclient'
},
Import{
mod: 'x.json2 as json'
types: ['Any']
}
]
name: 'client_actor'
items: items
}
}
pub fn generate_example_client_file(spec ActorSpecification) !VFile {
actor_name_snake := texttools.snake_case(spec.name)
actor_name_pascal := texttools.snake_case_to_pascal(spec.name)
mut items := []CodeItem{}
items << CustomCode {'
pub struct Client {
stage.Client
}
fn new_client() !Client {
mut redis := redisclient.new(\'localhost:6379\')!
mut rpc_q := redis.rpc_get(\'actor_example_\${name}\')
return Client{
rpc: rpc_q
}
}'}
for method in spec.methods {
items << generate_client_method(method)!
}
return VFile {
imports: [
Import{
mod: 'freeflowuniverse.herolib.baobab.stage'
},
Import{
mod: 'freeflowuniverse.herolib.core.redisclient'
},
Import{
mod: 'x.json2 as json'
types: ['Any']
}
]
name: 'client'
items: items
}
}
pub fn generate_client_method(method ActorMethod) !Function {
name_fixed := texttools.snake_case(method.name)
call_params := if method.parameters.len > 0 {
method.parameters.map(texttools.snake_case(it.name)).map('Any(${it})').join(', ')
} else {''}
params_stmt := if method.parameters.len == 0 {
''
} else if method.parameters.len == 1 {
'params := json.encode(${texttools.snake_case(method.parameters[0].name)})'
} else {
'mut params_arr := []Any{}
params_arr = [${call_params}]
params := json.encode(params_arr.str())
'
}
mut client_call_stmt := "action := client.call_to_action(
name: '${name_fixed}'"
if params_stmt != '' {
client_call_stmt += 'params: params'
}
client_call_stmt += ')!'
result_type := schemaref_to_type(method.result.schema).vgen().trim_space()
result_stmt := if result_type == '' {
''
} else {
"return json.decode[${result_type}](action.result)!"
}
result_param := content_descriptor_to_parameter(method.result)!
return Function {
receiver: code.new_param(v: 'mut client Client')!
result: Param{...result_param, typ: Result{result_param.typ}}
name: name_fixed
body: '${params_stmt}\n${client_call_stmt}\n${result_stmt}'
summary: method.summary
description: method.description
params: method.parameters.map(content_descriptor_to_parameter(it)!)
}
}