This commit is contained in:
2025-09-02 08:52:51 +02:00
parent 3af0aef6c1
commit 418a38527a
8 changed files with 81 additions and 50 deletions

View File

@@ -0,0 +1,2 @@
example
client_example

View File

@@ -1,13 +1,13 @@
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import net.unix
import x.json2
import json
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.hero.heromodels.openrpc
fn send_request(mut conn unix.StreamConn, request openrpc.JsonRpcRequest) ! {
request_json := json2.encode(request)
request_json := json.encode(request)
conn.write_string(request_json)!
}
@@ -32,8 +32,8 @@ console.print_header('Test 1: Discover OpenRPC Specification')
discover_request := openrpc.JsonRpcRequest{
jsonrpc: '2.0'
method: 'discover'
params: json2.null
id: json2.Any(1)
params: 'null'
id: '1'
}
send_request(mut conn, discover_request)!
@@ -47,8 +47,8 @@ comment_json := '{"comment": "This is a test comment from OpenRPC client", "pare
create_request := openrpc.JsonRpcRequest{
jsonrpc: '2.0'
method: 'comment_set'
params: json2.raw_decode(comment_json)!
id: json2.Any(2)
params: comment_json
id: '2'
}
send_request(mut conn, create_request)!
@@ -60,8 +60,8 @@ console.print_header('Test 3: List All Comments')
list_request := openrpc.JsonRpcRequest{
jsonrpc: '2.0'
method: 'comment_list'
params: json2.null
id: json2.Any(3)
params: 'null'
id: '3'
}
send_request(mut conn, list_request)!
@@ -75,8 +75,8 @@ get_args_json := '{"author": 1}'
get_request := openrpc.JsonRpcRequest{
jsonrpc: '2.0'
method: 'comment_get'
params: json2.raw_decode(get_args_json)!
id: json2.Any(4)
params: get_args_json
id: '4'
}
send_request(mut conn, get_request)!

View File

@@ -1,17 +1,22 @@
module openrpc
import x.json2
import json
import freeflowuniverse.herolib.hero.heromodels
import freeflowuniverse.herolib.core.redisclient
// comment_get retrieves comments based on the provided arguments
fn (mut server RPCServer) comment_get(params json2.Any) !json2.Any {
args := json2.decode[CommentGetArgs](params.json_str())!
fn (mut server RPCServer) comment_get(params string) !string {
// Handle empty params
if params == 'null' || params == '{}' {
return error('No valid search criteria provided. Please specify id, author, or parent.')
}
args := json.decode(CommentGetArgs, params)!
// If ID is provided, get specific comment
if id := args.id {
comment := heromodels.comment_get(id)!
return json2.encode(comment)
return json.encode(comment)
}
// If author is provided, find comments by author
@@ -28,15 +33,15 @@ fn (mut server RPCServer) comment_get(params json2.Any) !json2.Any {
}
// comment_set creates or updates a comment
fn (mut server RPCServer) comment_set(params json2.Any) !json2.Any {
comment_arg := json2.decode[heromodels.CommentArg](params.json_str())!
fn (mut server RPCServer) comment_set(params string) !string {
comment_arg := json.decode(heromodels.CommentArg, params)!
id := heromodels.comment_set(comment_arg)!
return json2.encode({'id': id})
return json.encode({'id': id})
}
// comment_delete removes a comment by ID
fn (mut server RPCServer) comment_delete(params json2.Any) !json2.Any {
args := json2.decode[CommentDeleteArgs](params.json_str())!
fn (mut server RPCServer) comment_delete(params string) !string {
args := json.decode(CommentDeleteArgs, params)!
// Check if comment exists
if !heromodels.comment_exist(args.id)! {
@@ -48,11 +53,11 @@ fn (mut server RPCServer) comment_delete(params json2.Any) !json2.Any {
redis.hdel('db:comments:data', args.id.str())!
result_json := '{"success": true, "id": ${args.id}}'
return json2.raw_decode(result_json)!
return result_json
}
// comment_list returns all comment IDs
fn (mut server RPCServer) comment_list() !json2.Any {
fn (mut server RPCServer) comment_list() !string {
mut redis := redisclient.core_get()!
keys := redis.hkeys('db:comments:data')!
mut ids := []u32{}
@@ -61,11 +66,11 @@ fn (mut server RPCServer) comment_list() !json2.Any {
ids << key.u32()
}
return json2.encode(ids)
return json.encode(ids)
}
// Helper function to get comments by author
fn (mut server RPCServer) get_comments_by_author(author u32) !json2.Any {
fn (mut server RPCServer) get_comments_by_author(author u32) !string {
mut redis := redisclient.core_get()!
all_data := redis.hgetall('db:comments:data')!
mut matching_comments := []heromodels.Comment{}
@@ -77,11 +82,11 @@ fn (mut server RPCServer) get_comments_by_author(author u32) !json2.Any {
}
}
return json2.encode(matching_comments)
return json.encode(matching_comments)
}
// Helper function to get comments by parent
fn (mut server RPCServer) get_comments_by_parent(parent u32) !json2.Any {
fn (mut server RPCServer) get_comments_by_parent(parent u32) !string {
mut redis := redisclient.core_get()!
all_data := redis.hgetall('db:comments:data')!
mut matching_comments := []heromodels.Comment{}
@@ -93,5 +98,5 @@ fn (mut server RPCServer) get_comments_by_parent(parent u32) !json2.Any {
}
}
return json2.encode(matching_comments)
return json.encode(matching_comments)
}

View File

@@ -1,9 +1,7 @@
module openrpc
import freeflowuniverse.herolib.schemas.openrpc
import x.json2
// discover returns the OpenRPC specification for the HeroModels service
fn (mut server RPCServer) discover() !json2.Any {
fn (mut server RPCServer) discover() !string {
spec_json := $tmpl("openrpc.json")
return openrpc.decode_json_any(spec_json)!
return spec_json
}

View File

@@ -1,6 +1,7 @@
module openrpc
import json
import x.json2 { Any }
import net.unix
import os
import freeflowuniverse.herolib.ui.console
@@ -69,7 +70,7 @@ fn (mut server RPCServer) handle_connection(mut conn unix.StreamConn) {
// Process the JSON-RPC request
response := server.process_request(request_data) or {
server.create_error_response(-32603, 'Internal error: ${err}', json2.null)
server.create_error_response(-32603, 'Internal error: ${err}', 'null')
}
// Send response
@@ -81,19 +82,38 @@ fn (mut server RPCServer) handle_connection(mut conn unix.StreamConn) {
}
fn (mut server RPCServer) process_request(request_data string) !string {
// Parse JSON-RPC request
request := json2.decode[JsonRpcRequest](request_data)!
// Parse JSON-RPC request manually to handle params properly
request_map := json.decode(map[string]Any, request_data)!
jsonrpc := request_map['jsonrpc']!.str()
method := request_map['method']!.str()
id := request_map['id']!.str()
// Handle params - convert to string representation
params_str := if 'params' in request_map {
params_any := request_map['params']!
match params_any {
string {
params_any
}
else {
json.encode(params_any)
}
}
} else {
'null'
}
// Route to appropriate method
result := match request.method {
result := match method {
'comment_get' {
server.comment_get(request.params)!
server.comment_get(params_str)!
}
'comment_set' {
server.comment_set(request.params)!
server.comment_set(params_str)!
}
'comment_delete' {
server.comment_delete(request.params)!
server.comment_delete(params_str)!
}
'comment_list' {
server.comment_list()!
@@ -102,32 +122,32 @@ fn (mut server RPCServer) process_request(request_data string) !string {
server.discover()!
}
else {
return server.create_error_response(-32601, 'Method not found', request.id)
return server.create_error_response(-32601, 'Method not found', id)
}
}
return server.create_success_response(result, request.id)
return server.create_success_response(result, id)
}
fn (mut server RPCServer) create_success_response(result json2.Any, id json2.Any) string {
fn (mut server RPCServer) create_success_response(result string, id string) string {
response := JsonRpcResponse{
jsonrpc: '2.0'
result: result
id: id
}
return json2.encode(response)
return json.encode(response)
}
fn (mut server RPCServer) create_error_response(code int, message string, id json2.Any) string {
fn (mut server RPCServer) create_error_response(code int, message string, id string) string {
error := JsonRpcError{
code: code
message: message
data: json2.null
data: 'null'
}
response := JsonRpcResponse{
jsonrpc: '2.0'
error: error
id: id
}
return json2.encode(response)
return json.encode(response)
}

View File

@@ -1,23 +1,23 @@
module openrpc
import x.json2
import json
// JSON-RPC 2.0 request structure
pub struct JsonRpcRequest {
pub:
jsonrpc string = '2.0'
method string
params json2.Any
id json2.Any
params string
id string
}
// JSON-RPC 2.0 response structure
pub struct JsonRpcResponse {
pub:
jsonrpc string = '2.0'
result json2.Any
result string
error ?JsonRpcError
id json2.Any
id string
}
// JSON-RPC 2.0 error structure
@@ -25,7 +25,7 @@ pub struct JsonRpcError {
pub:
code int
message string
data json2.Any
data string
}
// Comment-specific argument structures

View File

@@ -9,6 +9,12 @@ pub fn decode_json_any(data string) !Any {
return json2.decode[json2.Any](data)!
}
pub fn decode_json_string(data string) !string {
mut o := decode(data)!
return json.encode(o)!
}
pub fn decode(data string) !OpenRPC {
// mut object := json.decode[OpenRPC](data) or { return error('Failed to decode json\n=======\n${data}\n===========\n${err}') }