diff --git a/lib/hero/heromodels/examples/.gitignore b/lib/hero/heromodels/examples/.gitignore new file mode 100644 index 00000000..9cf4400b --- /dev/null +++ b/lib/hero/heromodels/examples/.gitignore @@ -0,0 +1,2 @@ +example +client_example \ No newline at end of file diff --git a/lib/hero/heromodels/examples/client_example.vsh b/lib/hero/heromodels/examples/client_example.vsh index ec05e0af..c4822354 100755 --- a/lib/hero/heromodels/examples/client_example.vsh +++ b/lib/hero/heromodels/examples/client_example.vsh @@ -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)! diff --git a/lib/hero/heromodels/examples/example.vsh b/lib/hero/heromodels/examples/server_example.vsh old mode 100644 new mode 100755 similarity index 100% rename from lib/hero/heromodels/examples/example.vsh rename to lib/hero/heromodels/examples/server_example.vsh diff --git a/lib/hero/heromodels/openrpc/comment.v b/lib/hero/heromodels/openrpc/comment.v index 6e9205dc..bfc84d6b 100644 --- a/lib/hero/heromodels/openrpc/comment.v +++ b/lib/hero/heromodels/openrpc/comment.v @@ -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) } \ No newline at end of file diff --git a/lib/hero/heromodels/openrpc/discover.v b/lib/hero/heromodels/openrpc/discover.v index 2092501a..fb803cb4 100644 --- a/lib/hero/heromodels/openrpc/discover.v +++ b/lib/hero/heromodels/openrpc/discover.v @@ -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 } \ No newline at end of file diff --git a/lib/hero/heromodels/openrpc/server.v b/lib/hero/heromodels/openrpc/server.v index bef6f62c..9c4ae489 100644 --- a/lib/hero/heromodels/openrpc/server.v +++ b/lib/hero/heromodels/openrpc/server.v @@ -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) } \ No newline at end of file diff --git a/lib/hero/heromodels/openrpc/types.v b/lib/hero/heromodels/openrpc/types.v index ba571add..90fb383a 100644 --- a/lib/hero/heromodels/openrpc/types.v +++ b/lib/hero/heromodels/openrpc/types.v @@ -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 diff --git a/lib/schemas/openrpc/decode.v b/lib/schemas/openrpc/decode.v index 4ceff8ae..22755c20 100644 --- a/lib/schemas/openrpc/decode.v +++ b/lib/schemas/openrpc/decode.v @@ -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}') }