refactor: Update JSON parsing and schema inflation

- Use `json2.decode[json2.Any]` instead of `json2.raw_decode`
- Add `@[required]` to procedure function signatures
- Improve error handling for missing JSONRPC fields
- Update `encode` to use `prettify: true`
- Add checks for missing schema and content descriptor references
This commit is contained in:
Mahmoud-Emad
2025-10-22 17:44:37 +03:00
parent 37f0aa0e96
commit 0bfb5cfdd0
16 changed files with 783 additions and 1069 deletions

View File

@@ -86,13 +86,13 @@ pub fn (mut handler Handler) register_api_handler(groupname string, procedure_gr
pub struct Procedure[T, U] {
pub mut:
method string
function fn (T) !U
function fn (T) !U @[required]
}
pub struct ProcedureVoid[T] {
pub mut:
method string
function fn (T) !
function fn (T) ! @[required]
}
pub fn (pw Procedure[T, U]) handle(request Request) !Response {

View File

@@ -52,10 +52,10 @@ pub fn new_request(method string, params string) Request {
pub fn decode_request(data string) !Request {
mut r2 := json2.decode[json2.Any](data)!
mut r3 := r2.as_map()
a := r3['jsonrpc'].str()
b := r3['method'].str()
c := r3['params'].str()
d := r3['id'].int()
a := (r3['jsonrpc'] or { return error('jsonrpc field not found') }).str()
b := (r3['method'] or { return error('method field not found') }).str()
c := (r3['params'] or { return error('params field not found') }).str()
d := (r3['id'] or { return error('id field not found') }).int()
mut r4 := Request{
jsonrpc: a
method: b
@@ -70,7 +70,7 @@ pub fn decode_request(data string) !Request {
// Returns:
// - A JSON string representation of the Request
pub fn (req Request) encode() string {
return json2.encode_pretty(req)
return json2.encode(req, prettify: true)
}
// validate checks if the Request object contains all required fields
@@ -133,7 +133,7 @@ pub fn new_request_generic[T](method string, params T) RequestGeneric[T] {
// Returns:
// - The ID as a string, or an error if the ID field is missing
pub fn decode_request_id(data string) !int {
data_any := json2.raw_decode(data)!
data_any := json2.decode[json2.Any](data)!
data_map := data_any.as_map()
id_any := data_map['id'] or { return error('ID field not found') }
return id_any.int()
@@ -148,7 +148,7 @@ pub fn decode_request_id(data string) !int {
// Returns:
// - The method name as a string, or an error if the method field is missing
pub fn decode_request_method(data string) !string {
data_any := json2.raw_decode(data)!
data_any := json2.decode[json2.Any](data)!
data_map := data_any.as_map()
method_any := data_map['method'] or { return error('Method field not found') }
return method_any.str()

View File

@@ -105,7 +105,7 @@ pub fn new_error_response(id int, error RPCError) Response {
// Returns:
// - A Response object or an error if parsing fails or the response is invalid
pub fn decode_response(data string) !Response {
raw := json2.raw_decode(data) or {
raw := json2.decode[json2.Any](data) or {
return error('Failed to decode JSONRPC response ${data}\n${err}')
}
raw_map := raw.as_map()

View File

@@ -7,7 +7,7 @@ import json
// Handles complex fields like properties, additionalProperties, items, and examples
// that require custom parsing beyond standard JSON decoding.
pub fn decode(data string) !Schema {
schema_map := json2.raw_decode(data)!.as_map()
schema_map := json2.decode[Any](data)!.as_map()
mut schema := json.decode(Schema, data)!
// Process fields that require custom decoding

View File

@@ -19,7 +19,7 @@ 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}')
}
data_map := json2.raw_decode(data)!.as_map()
data_map := json2.decode[Any](data)!.as_map()
if 'components' in data_map {
object.components = decode_components(data_map) or {
return error('Failed to decode components\n${err}')

View File

@@ -12,7 +12,11 @@ pub fn (s OpenRPC) inflate_method(method Method) Method {
pub fn (s OpenRPC) inflate_content_descriptor(cd_ ContentDescriptorRef) ContentDescriptor {
cd := if cd_ is Reference {
s.components.content_descriptors[cd_.ref] as ContentDescriptor
ref_key := cd_.ref
descriptor_ref := s.components.content_descriptors[ref_key] or {
panic('Content descriptor not found: ${ref_key}')
}
descriptor_ref as ContentDescriptor
} else {
cd_ as ContentDescriptor
}
@@ -35,7 +39,9 @@ pub fn (s OpenRPC) inflate_schema(schema_ref SchemaRef) Schema {
panic('not implemented')
}
schema_name := schema_ref.ref.trim_string_left('#/components/schemas/')
s.inflate_schema(s.components.schemas[schema_name])
s.inflate_schema(s.components.schemas[schema_name] or {
panic('Schema not found: ${schema_name}')
})
} else {
schema_ref as Schema
}