...
This commit is contained in:
78
aiprompts/herolib_advanced/openrpcexample.json
Normal file
78
aiprompts/herolib_advanced/openrpcexample.json
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"openrpc": "1.0.0-rc1",
|
||||
"info": {
|
||||
"title": "Simple RPC overview",
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"methods": [
|
||||
{
|
||||
"name": "get_versions",
|
||||
"summary": "List API versions",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "get_version_result",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "v2",
|
||||
"summary": "its a v2 example pairing!",
|
||||
"description": "aight so this is how it works. You foo the bar then you baz the razmataz",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "versionsExample",
|
||||
"value": {
|
||||
"versions": [
|
||||
{
|
||||
"status": "CURRENT",
|
||||
"updated": "2011-01-21T11:33:21Z",
|
||||
"id": "v2.0",
|
||||
"urls": [
|
||||
{
|
||||
"href": "http://127.0.0.1:8774/v2/",
|
||||
"rel": "self"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"status": "EXPERIMENTAL",
|
||||
"updated": "2013-07-23T11:33:21Z",
|
||||
"id": "v3.0",
|
||||
"urls": [
|
||||
{
|
||||
"href": "http://127.0.0.1:8774/v3/",
|
||||
"rel": "self"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "get_version_details",
|
||||
"summary": "Show API version details",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "foo",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"name": "stringifiedVersionsExample",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "bliggityblaow",
|
||||
"value": "{\n \"versions\": [\n {\n \"status\": \"CURRENT\",\n \"updated\": \"2011-01-21T11:33:21Z\",\n \"id\": \"v2.0\",\n \"urls\": [\n {\n \"href\": \"http://127.0.0.1:8774/v2/\",\n \"rel\": \"self\"\n }\n ]\n },\n {\n \"status\": \"EXPERIMENTAL\",\n \"updated\": \"2013-07-23T11:33:21Z\",\n \"id\": \"v3.0\",\n \"urls\": [\n {\n \"href\": \"http://127.0.0.1:8774/v3/\",\n \"rel\": \"self\"\n }\n ]\n }\n ]\n}\n"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
212
aiprompts/v_core/json/cjson.md
Normal file
212
aiprompts/v_core/json/cjson.md
Normal file
@@ -0,0 +1,212 @@
|
||||
# module cjson
|
||||
|
||||
|
||||
## Contents
|
||||
- [create_array](#create_array)
|
||||
- [create_bool](#create_bool)
|
||||
- [create_false](#create_false)
|
||||
- [create_null](#create_null)
|
||||
- [create_number](#create_number)
|
||||
- [create_object](#create_object)
|
||||
- [create_raw](#create_raw)
|
||||
- [create_string](#create_string)
|
||||
- [create_true](#create_true)
|
||||
- [delete](#delete)
|
||||
- [version](#version)
|
||||
- [Node](#Node)
|
||||
- [add_item_to_object](#add_item_to_object)
|
||||
- [add_item_to_array](#add_item_to_array)
|
||||
- [print](#print)
|
||||
- [print_unformatted](#print_unformatted)
|
||||
- [str](#str)
|
||||
- [CJsonType](#CJsonType)
|
||||
- [C.cJSON](#C.cJSON)
|
||||
|
||||
## create_array
|
||||
```v
|
||||
fn create_array() &Node
|
||||
```
|
||||
|
||||
create_array creates a new JSON array item. Use .add_item_to_array(value) calls, to add items to it later.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_bool
|
||||
```v
|
||||
fn create_bool(val bool) &Node
|
||||
```
|
||||
|
||||
create_bool creates a new JSON boolean item.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_false
|
||||
```v
|
||||
fn create_false() &Node
|
||||
```
|
||||
|
||||
create_false creates a new JSON boolean item, with value `false`.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_null
|
||||
```v
|
||||
fn create_null() &Node
|
||||
```
|
||||
|
||||
create_null creates a new JSON NULL item, with the value `null`. It symbolises a missing value for a given key in an object.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_number
|
||||
```v
|
||||
fn create_number(val f64) &Node
|
||||
```
|
||||
|
||||
create_number creates a new JSON number item.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_object
|
||||
```v
|
||||
fn create_object() &Node
|
||||
```
|
||||
|
||||
create_object creates a new JSON object/map item. Use .add_item_to_object(key, value) calls, to add other items to it later.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_raw
|
||||
```v
|
||||
fn create_raw(const_val string) &Node
|
||||
```
|
||||
|
||||
create_raw creates a new JSON RAW string item.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_string
|
||||
```v
|
||||
fn create_string(val string) &Node
|
||||
```
|
||||
|
||||
create_string creates a new JSON string item.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## create_true
|
||||
```v
|
||||
fn create_true() &Node
|
||||
```
|
||||
|
||||
create_true creates a new JSON boolean item, with value `true`.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## delete
|
||||
```v
|
||||
fn delete(node &Node)
|
||||
```
|
||||
|
||||
delete removes the given node from memory. NB: DO NOT USE that node, after you have called `unsafe { delete(node) }` !
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## version
|
||||
```v
|
||||
fn version() string
|
||||
```
|
||||
|
||||
version returns the version of cJSON as a string.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Node
|
||||
```v
|
||||
type Node = C.cJSON
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## add_item_to_object
|
||||
```v
|
||||
fn (mut obj Node) add_item_to_object(key string, item &Node)
|
||||
```
|
||||
|
||||
add_item_to_array adds the given item to the object, under the given `key`.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## add_item_to_array
|
||||
```v
|
||||
fn (mut obj Node) add_item_to_array(item &Node)
|
||||
```
|
||||
|
||||
add_item_to_array append the given item to the object.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## print
|
||||
```v
|
||||
fn (mut obj Node) print() string
|
||||
```
|
||||
|
||||
print serialises the node to a string, formatting its structure, so the resulting string is more prettier/human readable.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## print_unformatted
|
||||
```v
|
||||
fn (mut obj Node) print_unformatted() string
|
||||
```
|
||||
|
||||
print serialises the node to a string, without formatting its structure, so the resulting string is shorter/cheaper to transmit.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## str
|
||||
```v
|
||||
fn (mut obj Node) str() string
|
||||
```
|
||||
|
||||
str returns the unformatted serialisation to string of the given Node.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## CJsonType
|
||||
```v
|
||||
enum CJsonType {
|
||||
t_false
|
||||
t_true
|
||||
t_null
|
||||
t_number
|
||||
t_string
|
||||
t_array
|
||||
t_object
|
||||
t_raw
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## C.cJSON
|
||||
```v
|
||||
struct C.cJSON {
|
||||
pub:
|
||||
next &C.cJSON // next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem
|
||||
prev &C.cJSON
|
||||
child &C.cJSON // An array or object item will have a child pointer pointing to a chain of the items in the array/object
|
||||
|
||||
type CJsonType // The type of the item, as above
|
||||
|
||||
valueint int // writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead
|
||||
valuedouble f64 // The item's number, if type==cJSON_Number
|
||||
valuestring &char // The item's string, if type==cJSON_String and type == cJSON_Raw
|
||||
// @string &char // The item's name string, if this item is the child of, or is in the list of subitems of an object
|
||||
// TODO: `@string &char` from above does not work. It should be fixed, at least inside `struct C.`.
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
#### Powered by vdoc. Generated on: 2 Sep 2025 07:37:38
|
||||
48
aiprompts/v_core/json/json.md
Normal file
48
aiprompts/v_core/json/json.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# module json
|
||||
|
||||
|
||||
## Contents
|
||||
- [decode](#decode)
|
||||
- [encode](#encode)
|
||||
- [encode_pretty](#encode_pretty)
|
||||
- [C.cJSON](#C.cJSON)
|
||||
|
||||
## decode
|
||||
```v
|
||||
fn decode(typ voidptr, s string) !voidptr
|
||||
```
|
||||
|
||||
decode tries to decode the provided JSON string, into a V structure. If it can not do that, it returns an error describing the reason for the parsing failure.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## encode
|
||||
```v
|
||||
fn encode(x voidptr) string
|
||||
```
|
||||
|
||||
encode serialises the provided V value as a JSON string, optimised for shortness.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## encode_pretty
|
||||
```v
|
||||
fn encode_pretty(x voidptr) string
|
||||
```
|
||||
|
||||
encode_pretty serialises the provided V value as a JSON string, in a formatted way, optimised for viewing by humans.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## C.cJSON
|
||||
```v
|
||||
struct C.cJSON {
|
||||
valueint int
|
||||
valuedouble f64
|
||||
valuestring &char
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
#### Powered by vdoc. Generated on: 2 Sep 2025 07:37:38
|
||||
100
aiprompts/v_core/json2/decoder2.md
Normal file
100
aiprompts/v_core/json2/decoder2.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# module decoder2
|
||||
|
||||
|
||||
## Contents
|
||||
- [decode](#decode)
|
||||
- [decode_array](#decode_array)
|
||||
- [BooleanDecoder](#BooleanDecoder)
|
||||
- [NullDecoder](#NullDecoder)
|
||||
- [NumberDecoder](#NumberDecoder)
|
||||
- [StringDecoder](#StringDecoder)
|
||||
- [JsonDecodeError](#JsonDecodeError)
|
||||
|
||||
## decode
|
||||
```v
|
||||
fn decode[T](val string) !T
|
||||
```
|
||||
|
||||
decode decodes a JSON string into a specified type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## decode_array
|
||||
```v
|
||||
fn decode_array[T](src string) !T
|
||||
```
|
||||
|
||||
decode_array is a generic function that decodes a JSON string into the array target type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## BooleanDecoder
|
||||
```v
|
||||
interface BooleanDecoder {
|
||||
mut:
|
||||
// called with converted bool
|
||||
// already checked so no error needed
|
||||
from_json_boolean(boolean_value bool)
|
||||
}
|
||||
```
|
||||
|
||||
implements decoding json true/false
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## NullDecoder
|
||||
```v
|
||||
interface NullDecoder {
|
||||
mut:
|
||||
// only has one value
|
||||
// already checked so no error needed
|
||||
from_json_null()
|
||||
}
|
||||
```
|
||||
|
||||
implements decoding json null
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## NumberDecoder
|
||||
```v
|
||||
interface NumberDecoder {
|
||||
mut:
|
||||
// called with raw string of number e.g. '-1.234e23'
|
||||
from_json_number(raw_number string) !
|
||||
}
|
||||
```
|
||||
|
||||
implements decoding json numbers, e.g. -1.234e23
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## StringDecoder
|
||||
```v
|
||||
interface StringDecoder {
|
||||
mut:
|
||||
// called with raw string (minus apostrophes) e.g. 'hello, \u2164!'
|
||||
from_json_string(raw_string string) !
|
||||
}
|
||||
```
|
||||
|
||||
implements decoding json strings, e.g. "hello, \u2164!"
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## JsonDecodeError
|
||||
```v
|
||||
struct JsonDecodeError {
|
||||
Error
|
||||
context string
|
||||
pub:
|
||||
message string
|
||||
|
||||
line int
|
||||
character int
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
#### Powered by vdoc. Generated on: 2 Sep 2025 07:37:54
|
||||
63
aiprompts/v_core/json2/strict.md
Normal file
63
aiprompts/v_core/json2/strict.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# module strict
|
||||
|
||||
|
||||
## Contents
|
||||
- [get_keys_from_json](#get_keys_from_json)
|
||||
- [strict_check](#strict_check)
|
||||
- [KeyType](#KeyType)
|
||||
- [KeyStruct](#KeyStruct)
|
||||
- [StructCheckResult](#StructCheckResult)
|
||||
|
||||
## get_keys_from_json
|
||||
```v
|
||||
fn get_keys_from_json(tokens []string) []KeyStruct
|
||||
```
|
||||
|
||||
get_keys_from_json .
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## strict_check
|
||||
```v
|
||||
fn strict_check[T](json_data string) StructCheckResult
|
||||
```
|
||||
|
||||
strict_check .
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## KeyType
|
||||
```v
|
||||
enum KeyType {
|
||||
literal
|
||||
map
|
||||
array
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## KeyStruct
|
||||
```v
|
||||
struct KeyStruct {
|
||||
pub:
|
||||
key string
|
||||
value_type KeyType
|
||||
token_pos int // the position of the token
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## StructCheckResult
|
||||
```v
|
||||
struct StructCheckResult {
|
||||
pub:
|
||||
duplicates []string
|
||||
superfluous []string
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
#### Powered by vdoc. Generated on: 2 Sep 2025 07:37:54
|
||||
490
aiprompts/v_core/json2/x.json2.md
Normal file
490
aiprompts/v_core/json2/x.json2.md
Normal file
@@ -0,0 +1,490 @@
|
||||
# module x.json2
|
||||
|
||||
|
||||
## Contents
|
||||
- [Constants](#Constants)
|
||||
- [decode](#decode)
|
||||
- [decode_array](#decode_array)
|
||||
- [encode](#encode)
|
||||
- [encode_pretty](#encode_pretty)
|
||||
- [fast_raw_decode](#fast_raw_decode)
|
||||
- [map_from](#map_from)
|
||||
- [raw_decode](#raw_decode)
|
||||
- [Encodable](#Encodable)
|
||||
- [Any](#Any)
|
||||
- [arr](#arr)
|
||||
- [as_map](#as_map)
|
||||
- [as_map_of_strings](#as_map_of_strings)
|
||||
- [bool](#bool)
|
||||
- [f32](#f32)
|
||||
- [f64](#f64)
|
||||
- [i16](#i16)
|
||||
- [i32](#i32)
|
||||
- [i64](#i64)
|
||||
- [i8](#i8)
|
||||
- [int](#int)
|
||||
- [json_str](#json_str)
|
||||
- [prettify_json_str](#prettify_json_str)
|
||||
- [str](#str)
|
||||
- [to_time](#to_time)
|
||||
- [u16](#u16)
|
||||
- [u32](#u32)
|
||||
- [u64](#u64)
|
||||
- [u8](#u8)
|
||||
- [Parser](#Parser)
|
||||
- [decode](#decode)
|
||||
- [[]Any](#[]Any)
|
||||
- [str](#str)
|
||||
- [map[string]Any](#map[string]Any)
|
||||
- [str](#str)
|
||||
- [DecodeError](#DecodeError)
|
||||
- [code](#code)
|
||||
- [msg](#msg)
|
||||
- [Encoder](#Encoder)
|
||||
- [encode_value](#encode_value)
|
||||
- [InvalidTokenError](#InvalidTokenError)
|
||||
- [code](#code)
|
||||
- [msg](#msg)
|
||||
- [Null](#Null)
|
||||
- [from_json_null](#from_json_null)
|
||||
- [Token](#Token)
|
||||
- [full_col](#full_col)
|
||||
- [UnknownTokenError](#UnknownTokenError)
|
||||
- [code](#code)
|
||||
- [msg](#msg)
|
||||
|
||||
## Constants
|
||||
```v
|
||||
const null = Null{}
|
||||
```
|
||||
|
||||
null is an instance of the Null type, to ease comparisons with it.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## decode
|
||||
```v
|
||||
fn decode[T](src string) !T
|
||||
```
|
||||
|
||||
decode is a generic function that decodes a JSON string into the target type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## decode_array
|
||||
```v
|
||||
fn decode_array[T](src string) ![]T
|
||||
```
|
||||
|
||||
decode_array is a generic function that decodes a JSON string into the array target type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## encode
|
||||
```v
|
||||
fn encode[T](val T) string
|
||||
```
|
||||
|
||||
encode is a generic function that encodes a type into a JSON string.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## encode_pretty
|
||||
```v
|
||||
fn encode_pretty[T](typed_data T) string
|
||||
```
|
||||
|
||||
encode_pretty ...
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## fast_raw_decode
|
||||
```v
|
||||
fn fast_raw_decode(src string) !Any
|
||||
```
|
||||
|
||||
Same with `raw_decode`, but skips the type conversion for certain types when decoding a certain value.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## map_from
|
||||
```v
|
||||
fn map_from[T](t T) map[string]Any
|
||||
```
|
||||
|
||||
map_from converts a struct to a map of Any.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## raw_decode
|
||||
```v
|
||||
fn raw_decode(src string) !Any
|
||||
```
|
||||
|
||||
Decodes a JSON string into an `Any` type. Returns an option.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Encodable
|
||||
```v
|
||||
interface Encodable {
|
||||
json_str() string
|
||||
}
|
||||
```
|
||||
|
||||
Encodable is an interface, that allows custom implementations for encoding structs to their string based JSON representations.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Any
|
||||
## arr
|
||||
```v
|
||||
fn (f Any) arr() []Any
|
||||
```
|
||||
|
||||
arr uses `Any` as an array.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## as_map
|
||||
```v
|
||||
fn (f Any) as_map() map[string]Any
|
||||
```
|
||||
|
||||
as_map uses `Any` as a map.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## as_map_of_strings
|
||||
```v
|
||||
fn (f Any) as_map_of_strings() map[string]string
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## bool
|
||||
```v
|
||||
fn (f Any) bool() bool
|
||||
```
|
||||
|
||||
bool uses `Any` as a bool.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## f32
|
||||
```v
|
||||
fn (f Any) f32() f32
|
||||
```
|
||||
|
||||
f32 uses `Any` as a 32-bit float.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## f64
|
||||
```v
|
||||
fn (f Any) f64() f64
|
||||
```
|
||||
|
||||
f64 uses `Any` as a 64-bit float.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## i16
|
||||
```v
|
||||
fn (f Any) i16() i16
|
||||
```
|
||||
|
||||
i16 uses `Any` as a 16-bit integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## i32
|
||||
```v
|
||||
fn (f Any) i32() i32
|
||||
```
|
||||
|
||||
i32 uses `Any` as a 32-bit integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## i64
|
||||
```v
|
||||
fn (f Any) i64() i64
|
||||
```
|
||||
|
||||
i64 uses `Any` as a 64-bit integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## i8
|
||||
```v
|
||||
fn (f Any) i8() i8
|
||||
```
|
||||
|
||||
i8 uses `Any` as a 16-bit integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## int
|
||||
```v
|
||||
fn (f Any) int() int
|
||||
```
|
||||
|
||||
int uses `Any` as an integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## json_str
|
||||
```v
|
||||
fn (f Any) json_str() string
|
||||
```
|
||||
|
||||
json_str returns the JSON string representation of the `Any` type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## prettify_json_str
|
||||
```v
|
||||
fn (f Any) prettify_json_str() string
|
||||
```
|
||||
|
||||
prettify_json_str returns the pretty-formatted JSON string representation of the `Any` type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## str
|
||||
```v
|
||||
fn (f Any) str() string
|
||||
```
|
||||
|
||||
str returns the string representation of the `Any` type. Use the `json_str` method. If you want to use the escaped str() version of the `Any` type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## to_time
|
||||
```v
|
||||
fn (f Any) to_time() !time.Time
|
||||
```
|
||||
|
||||
to_time uses `Any` as a time.Time.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## u16
|
||||
```v
|
||||
fn (f Any) u16() u16
|
||||
```
|
||||
|
||||
u16 uses `Any` as a 16-bit unsigned integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## u32
|
||||
```v
|
||||
fn (f Any) u32() u32
|
||||
```
|
||||
|
||||
u32 uses `Any` as a 32-bit unsigned integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## u64
|
||||
```v
|
||||
fn (f Any) u64() u64
|
||||
```
|
||||
|
||||
u64 uses `Any` as a 64-bit unsigned integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## u8
|
||||
```v
|
||||
fn (f Any) u8() u8
|
||||
```
|
||||
|
||||
u8 uses `Any` as a 8-bit unsigned integer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Parser
|
||||
## decode
|
||||
```v
|
||||
fn (mut p Parser) decode() !Any
|
||||
```
|
||||
|
||||
decode - decodes provided JSON
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## []Any
|
||||
## str
|
||||
```v
|
||||
fn (f []Any) str() string
|
||||
```
|
||||
|
||||
str returns the JSON string representation of the `[]Any` type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## map[string]Any
|
||||
## str
|
||||
```v
|
||||
fn (f map[string]Any) str() string
|
||||
```
|
||||
|
||||
str returns the JSON string representation of the `map[string]Any` type.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## DecodeError
|
||||
```v
|
||||
struct DecodeError {
|
||||
line int
|
||||
column int
|
||||
message string
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## code
|
||||
```v
|
||||
fn (err DecodeError) code() int
|
||||
```
|
||||
|
||||
code returns the error code of DecodeError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## msg
|
||||
```v
|
||||
fn (err DecodeError) msg() string
|
||||
```
|
||||
|
||||
msg returns the message of the DecodeError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Encoder
|
||||
```v
|
||||
struct Encoder {
|
||||
pub:
|
||||
newline u8
|
||||
newline_spaces_count int
|
||||
escape_unicode bool = true
|
||||
}
|
||||
```
|
||||
|
||||
Encoder encodes the an `Any` type into JSON representation. It provides parameters in order to change the end result.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## encode_value
|
||||
```v
|
||||
fn (e &Encoder) encode_value[T](val T, mut buf []u8) !
|
||||
```
|
||||
|
||||
encode_value encodes a value to the specific buffer.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## InvalidTokenError
|
||||
```v
|
||||
struct InvalidTokenError {
|
||||
DecodeError
|
||||
token Token
|
||||
expected TokenKind
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## code
|
||||
```v
|
||||
fn (err InvalidTokenError) code() int
|
||||
```
|
||||
|
||||
code returns the error code of the InvalidTokenError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## msg
|
||||
```v
|
||||
fn (err InvalidTokenError) msg() string
|
||||
```
|
||||
|
||||
msg returns the message of the InvalidTokenError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Null
|
||||
```v
|
||||
struct Null {
|
||||
is_null bool = true
|
||||
}
|
||||
```
|
||||
|
||||
Null is a simple representation of the `null` value in JSON.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## from_json_null
|
||||
```v
|
||||
fn (mut n Null) from_json_null()
|
||||
```
|
||||
|
||||
from_json_null implements a custom decoder for json2
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## Token
|
||||
```v
|
||||
struct Token {
|
||||
lit []u8 // literal representation of the token
|
||||
kind TokenKind // the token number/enum; for quick comparisons
|
||||
line int // the line in the source where the token occurred
|
||||
col int // the column in the source where the token occurred
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## full_col
|
||||
```v
|
||||
fn (t Token) full_col() int
|
||||
```
|
||||
|
||||
full_col returns the full column information which includes the length.
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## UnknownTokenError
|
||||
```v
|
||||
struct UnknownTokenError {
|
||||
DecodeError
|
||||
token Token
|
||||
kind ValueKind = .unknown
|
||||
}
|
||||
```
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## code
|
||||
```v
|
||||
fn (err UnknownTokenError) code() int
|
||||
```
|
||||
|
||||
code returns the error code of the UnknownTokenError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
## msg
|
||||
```v
|
||||
fn (err UnknownTokenError) msg() string
|
||||
```
|
||||
|
||||
msg returns the error message of the UnknownTokenError
|
||||
|
||||
[[Return to contents]](#Contents)
|
||||
|
||||
#### Powered by vdoc. Generated on: 2 Sep 2025 07:37:54
|
||||
27
lib/hero/heromodels/ai_openrpcprompt.md
Normal file
27
lib/hero/heromodels/ai_openrpcprompt.md
Normal file
@@ -0,0 +1,27 @@
|
||||
lets make an openrpc server
|
||||
over unixsocker
|
||||
|
||||
on /tmp/heromodels
|
||||
|
||||
put code in lib/hero/heromodels/openrpc
|
||||
|
||||
do example for comment.v
|
||||
|
||||
make struct called RPCServer
|
||||
|
||||
put as methods
|
||||
|
||||
- comment_get(args CommentGetArgs)[]Comment! //chose the params well is @[params] struct CommentGetArgs always with id… in this case maybe author. …
|
||||
- walk over the hset with data, find the one we are looking for based on the args
|
||||
- comment_set(obj Comment)!
|
||||
- comment_delete(id…)
|
||||
- comment_list() ![]u32
|
||||
- discover()!string //returns a full openrpc spec
|
||||
|
||||
make one .v file per type of object now comment_…
|
||||
|
||||
we will then do for the other objects too
|
||||
|
||||
also generate the openrpc spec based on the methods we have and the objects we return
|
||||
|
||||
|
||||
130
lib/hero/heromodels/openrpc/README.md
Normal file
130
lib/hero/heromodels/openrpc/README.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# HeroModels OpenRPC Server
|
||||
|
||||
This module provides an OpenRPC server for HeroModels that runs over Unix domain sockets. It exposes comment management functionality through a JSON-RPC 2.0 interface.
|
||||
|
||||
## Features
|
||||
|
||||
- **Unix Socket Communication**: Efficient local communication via Unix domain sockets
|
||||
- **JSON-RPC 2.0 Protocol**: Standard JSON-RPC 2.0 implementation
|
||||
- **Comment Management**: Full CRUD operations for comments
|
||||
- **OpenRPC Specification**: Auto-generated OpenRPC spec via `discover` method
|
||||
- **Concurrent Handling**: Multiple client connections supported
|
||||
|
||||
## API Methods
|
||||
|
||||
### comment_get
|
||||
Retrieve comments by ID, author, or parent.
|
||||
|
||||
**Parameters:**
|
||||
- `id` (optional): Comment ID to retrieve
|
||||
- `author` (optional): Author ID to filter by
|
||||
- `parent` (optional): Parent comment ID to filter by
|
||||
|
||||
**Returns:** Comment object or array of comments
|
||||
|
||||
### comment_set
|
||||
Create a new comment.
|
||||
|
||||
**Parameters:**
|
||||
- `comment`: Comment text content
|
||||
- `parent`: Parent comment ID (0 for top-level)
|
||||
- `author`: Author user ID
|
||||
|
||||
**Returns:** Object with created comment ID
|
||||
|
||||
### comment_delete
|
||||
Delete a comment by ID.
|
||||
|
||||
**Parameters:**
|
||||
- `id`: Comment ID to delete
|
||||
|
||||
**Returns:** Success status and deleted comment ID
|
||||
|
||||
### comment_list
|
||||
List all comment IDs.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:** Array of all comment IDs
|
||||
|
||||
### discover
|
||||
Get the OpenRPC specification for this service.
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Returns:** Complete OpenRPC specification object
|
||||
|
||||
## Usage
|
||||
|
||||
### Starting the Server
|
||||
|
||||
```v
|
||||
import freeflowuniverse.herolib.hero.heromodels.openrpc
|
||||
|
||||
mut server := openrpc.new_rpc_server(socket_path: '/tmp/heromodels')!
|
||||
server.start()! // Blocks and serves requests
|
||||
```
|
||||
|
||||
### Example Client
|
||||
|
||||
```v
|
||||
import net.unix
|
||||
import json
|
||||
import freeflowuniverse.herolib.hero.heromodels.openrpc
|
||||
|
||||
// Connect to server
|
||||
mut conn := unix.connect_stream('/tmp/heromodels')!
|
||||
|
||||
// Create a comment
|
||||
request := openrpc.JsonRpcRequest{
|
||||
jsonrpc: '2.0'
|
||||
method: 'comment_set'
|
||||
params: json.encode({
|
||||
'comment': 'Hello World'
|
||||
'parent': 0
|
||||
'author': 1
|
||||
})
|
||||
id: 1
|
||||
}
|
||||
|
||||
// Send request
|
||||
conn.write_string(json.encode(request))!
|
||||
|
||||
// Read response
|
||||
mut buffer := []u8{len: 4096}
|
||||
bytes_read := conn.read(mut buffer)!
|
||||
response := buffer[..bytes_read].bytestr()
|
||||
```
|
||||
|
||||
## Files
|
||||
|
||||
- `server.v` - Main RPC server implementation
|
||||
- `types.v` - JSON-RPC and parameter type definitions
|
||||
- `comment.v` - Comment-specific RPC method implementations
|
||||
- `discover.v` - OpenRPC specification generation
|
||||
- `example.vsh` - Server example script
|
||||
- `client_example.vsh` - Client example script
|
||||
|
||||
## Running Examples
|
||||
|
||||
Start the server:
|
||||
```bash
|
||||
vrun lib/hero/heromodels/openrpc/example.vsh
|
||||
```
|
||||
|
||||
Test with client (in another terminal):
|
||||
```bash
|
||||
vrun lib/hero/heromodels/openrpc/client_example.vsh
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Redis (for data storage via heromodels)
|
||||
- Unix domain socket support
|
||||
- JSON encoding/decoding
|
||||
|
||||
## Socket Path
|
||||
|
||||
Default socket path: `/tmp/heromodels`
|
||||
|
||||
The socket file is automatically cleaned up when the server starts and stops.
|
||||
88
lib/hero/heromodels/openrpc/client_example.vsh
Normal file
88
lib/hero/heromodels/openrpc/client_example.vsh
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/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 freeflowuniverse.herolib.ui.console
|
||||
import freeflowuniverse.herolib.hero.heromodels.openrpc
|
||||
|
||||
// Example client to test the HeroModels OpenRPC server
|
||||
fn main() {
|
||||
console.print_header('HeroModels OpenRPC Client Example')
|
||||
|
||||
// Connect to the server
|
||||
mut conn := unix.connect_stream('/tmp/heromodels')!
|
||||
defer {
|
||||
conn.close() or {}
|
||||
}
|
||||
|
||||
console.print_item('Connected to server')
|
||||
|
||||
// Test 1: Get OpenRPC specification
|
||||
console.print_header('Test 1: Discover OpenRPC Specification')
|
||||
discover_request := openrpc.JsonRpcRequest{
|
||||
jsonrpc: '2.0'
|
||||
method: 'discover'
|
||||
params: json2.null
|
||||
id: json2.Any(1)
|
||||
}
|
||||
|
||||
send_request(mut conn, discover_request)!
|
||||
response := read_response(mut conn)!
|
||||
console.print_item('OpenRPC Spec received: ${response.len} characters')
|
||||
|
||||
// Test 2: Create a comment
|
||||
console.print_header('Test 2: Create Comment')
|
||||
comment_json := '{"comment": "This is a test comment from OpenRPC client", "parent": 0, "author": 1}'
|
||||
|
||||
create_request := openrpc.JsonRpcRequest{
|
||||
jsonrpc: '2.0'
|
||||
method: 'comment_set'
|
||||
params: json2.raw_decode(comment_json)!
|
||||
id: json2.Any(2)
|
||||
}
|
||||
|
||||
send_request(mut conn, create_request)!
|
||||
create_response := read_response(mut conn)!
|
||||
console.print_item('Comment created: ${create_response}')
|
||||
|
||||
// Test 3: List all comments
|
||||
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)
|
||||
}
|
||||
|
||||
send_request(mut conn, list_request)!
|
||||
list_response := read_response(mut conn)!
|
||||
console.print_item('Comment list: ${list_response}')
|
||||
|
||||
// Test 4: Get comment by author
|
||||
console.print_header('Test 4: Get Comments by Author')
|
||||
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)
|
||||
}
|
||||
|
||||
send_request(mut conn, get_request)!
|
||||
get_response := read_response(mut conn)!
|
||||
console.print_item('Comments by author: ${get_response}')
|
||||
|
||||
console.print_header('All tests completed successfully!')
|
||||
}
|
||||
|
||||
fn send_request(mut conn unix.StreamConn, request openrpc.JsonRpcRequest) ! {
|
||||
request_json := json2.encode(request)
|
||||
conn.write_string(request_json)!
|
||||
}
|
||||
|
||||
fn read_response(mut conn unix.StreamConn) !string {
|
||||
mut buffer := []u8{len: 8192}
|
||||
bytes_read := conn.read(mut buffer)!
|
||||
return buffer[..bytes_read].bytestr()
|
||||
}
|
||||
97
lib/hero/heromodels/openrpc/comment.v
Normal file
97
lib/hero/heromodels/openrpc/comment.v
Normal file
@@ -0,0 +1,97 @@
|
||||
module openrpc
|
||||
|
||||
import x.json2
|
||||
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())!
|
||||
|
||||
// If ID is provided, get specific comment
|
||||
if id := args.id {
|
||||
comment := heromodels.comment_get(id)!
|
||||
return json2.encode(comment)
|
||||
}
|
||||
|
||||
// If author is provided, find comments by author
|
||||
if author := args.author {
|
||||
return server.get_comments_by_author(author)!
|
||||
}
|
||||
|
||||
// If parent is provided, find child comments
|
||||
if parent := args.parent {
|
||||
return server.get_comments_by_parent(parent)!
|
||||
}
|
||||
|
||||
return error('No valid search criteria provided. Please specify id, author, or parent.')
|
||||
}
|
||||
|
||||
// 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())!
|
||||
id := heromodels.comment_set(comment_arg)!
|
||||
return json2.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())!
|
||||
|
||||
// Check if comment exists
|
||||
if !heromodels.comment_exist(args.id)! {
|
||||
return error('Comment with id ${args.id} does not exist')
|
||||
}
|
||||
|
||||
// Delete from Redis
|
||||
mut redis := redisclient.core_get()!
|
||||
redis.hdel('db:comments:data', args.id.str())!
|
||||
|
||||
result_json := '{"success": true, "id": ${args.id}}'
|
||||
return json2.raw_decode(result_json)!
|
||||
}
|
||||
|
||||
// comment_list returns all comment IDs
|
||||
fn (mut server RPCServer) comment_list() !json2.Any {
|
||||
mut redis := redisclient.core_get()!
|
||||
keys := redis.hkeys('db:comments:data')!
|
||||
mut ids := []u32{}
|
||||
|
||||
for key in keys {
|
||||
ids << key.u32()
|
||||
}
|
||||
|
||||
return json2.encode(ids)
|
||||
}
|
||||
|
||||
// Helper function to get comments by author
|
||||
fn (mut server RPCServer) get_comments_by_author(author u32) !json2.Any {
|
||||
mut redis := redisclient.core_get()!
|
||||
all_data := redis.hgetall('db:comments:data')!
|
||||
mut matching_comments := []heromodels.Comment{}
|
||||
|
||||
for _, data in all_data {
|
||||
comment := heromodels.comment_load(data.bytes())!
|
||||
if comment.author == author {
|
||||
matching_comments << comment
|
||||
}
|
||||
}
|
||||
|
||||
return json2.encode(matching_comments)
|
||||
}
|
||||
|
||||
// Helper function to get comments by parent
|
||||
fn (mut server RPCServer) get_comments_by_parent(parent u32) !json2.Any {
|
||||
mut redis := redisclient.core_get()!
|
||||
all_data := redis.hgetall('db:comments:data')!
|
||||
mut matching_comments := []heromodels.Comment{}
|
||||
|
||||
for _, data in all_data {
|
||||
comment := heromodels.comment_load(data.bytes())!
|
||||
if comment.parent == parent {
|
||||
matching_comments << comment
|
||||
}
|
||||
}
|
||||
|
||||
return json2.encode(matching_comments)
|
||||
}
|
||||
9
lib/hero/heromodels/openrpc/discover.v
Normal file
9
lib/hero/heromodels/openrpc/discover.v
Normal file
@@ -0,0 +1,9 @@
|
||||
module openrpc
|
||||
|
||||
import x.json2
|
||||
|
||||
// discover returns the OpenRPC specification for the HeroModels service
|
||||
fn (mut server RPCServer) discover() !string {
|
||||
spec_json := $tmpl("openrpc.json")
|
||||
return spec_json
|
||||
}
|
||||
26
lib/hero/heromodels/openrpc/example.vsh
Normal file
26
lib/hero/heromodels/openrpc/example.vsh
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import freeflowuniverse.herolib.hero.heromodels.openrpc
|
||||
import freeflowuniverse.herolib.hero.heromodels
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
import time
|
||||
import os
|
||||
|
||||
// Example usage of the HeroModels OpenRPC server
|
||||
fn main() {
|
||||
console.print_header('HeroModels OpenRPC Server Example')
|
||||
|
||||
// Create and start the server
|
||||
mut server := openrpc.new_rpc_server(socket_path: '/tmp/heromodels')!
|
||||
|
||||
// Start server in a separate thread
|
||||
spawn server.start()
|
||||
|
||||
console.print_item('Server started on /tmp/heromodels')
|
||||
console.print_item('Press Ctrl+C to stop the server')
|
||||
|
||||
// Keep the main thread alive
|
||||
for {
|
||||
time.sleep(1 * time.second)
|
||||
}
|
||||
}
|
||||
213
lib/hero/heromodels/openrpc/openrpc.json
Normal file
213
lib/hero/heromodels/openrpc/openrpc.json
Normal file
@@ -0,0 +1,213 @@
|
||||
{
|
||||
"openrpc": "1.0.0-rc1",
|
||||
"info": {
|
||||
"version": "1.0.0",
|
||||
"title": "HeroModels OpenRPC API",
|
||||
"description": "OpenRPC API for HeroModels comment management over Unix socket",
|
||||
"contact": {
|
||||
"name": "HeroLib Team",
|
||||
"url": "https://github.com/freeflowuniverse/herolib"
|
||||
}
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"name": "Unix Socket Server",
|
||||
"url": "${server.socket_path}",
|
||||
"description": "Unix domain socket server for HeroModels"
|
||||
}
|
||||
],
|
||||
"methods": [
|
||||
{
|
||||
"name": "comment_get",
|
||||
"description": "Retrieve comments by ID, author, or parent",
|
||||
"params": [
|
||||
{
|
||||
"name": "args",
|
||||
"description": "Comment search arguments",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "Comment ID to retrieve"
|
||||
},
|
||||
"author": {
|
||||
"type": "integer",
|
||||
"description": "Author ID to filter by"
|
||||
},
|
||||
"parent": {
|
||||
"type": "integer",
|
||||
"description": "Parent comment ID to filter by"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "comments",
|
||||
"description": "Comment(s) matching the criteria",
|
||||
"schema": {
|
||||
"oneOf": [
|
||||
{
|
||||
"\\$ref": "#/components/schemas/Comment"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"\\$ref": "#/components/schemas/Comment"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "comment_set",
|
||||
"description": "Create a new comment",
|
||||
"params": [
|
||||
{
|
||||
"name": "comment",
|
||||
"description": "Comment data to create",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"\\$ref": "#/components/schemas/CommentArg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "result",
|
||||
"description": "Created comment ID",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "ID of the created comment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "comment_delete",
|
||||
"description": "Delete a comment by ID",
|
||||
"params": [
|
||||
{
|
||||
"name": "args",
|
||||
"description": "Comment deletion arguments",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "ID of comment to delete",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"name": "result",
|
||||
"description": "Deletion result",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "comment_list",
|
||||
"description": "List all comment IDs",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "ids",
|
||||
"description": "Array of all comment IDs",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "discover",
|
||||
"description": "Get the OpenRPC specification for this service",
|
||||
"params": [],
|
||||
"result": {
|
||||
"name": "spec",
|
||||
"description": "OpenRPC specification",
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"components": {
|
||||
"schemas": {
|
||||
"Comment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "Unique comment identifier"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string",
|
||||
"description": "Comment text content"
|
||||
},
|
||||
"parent": {
|
||||
"type": "integer",
|
||||
"description": "Parent comment ID (0 if top-level)"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "integer",
|
||||
"description": "Unix timestamp of last update"
|
||||
},
|
||||
"author": {
|
||||
"type": "integer",
|
||||
"description": "Author user ID"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"id",
|
||||
"comment",
|
||||
"parent",
|
||||
"updated_at",
|
||||
"author"
|
||||
]
|
||||
},
|
||||
"CommentArg": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"type": "string",
|
||||
"description": "Comment text content"
|
||||
},
|
||||
"parent": {
|
||||
"type": "integer",
|
||||
"description": "Parent comment ID (0 if top-level)"
|
||||
},
|
||||
"author": {
|
||||
"type": "integer",
|
||||
"description": "Author user ID"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"comment",
|
||||
"author"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
133
lib/hero/heromodels/openrpc/server.v
Normal file
133
lib/hero/heromodels/openrpc/server.v
Normal file
@@ -0,0 +1,133 @@
|
||||
module openrpc
|
||||
|
||||
import x.json2
|
||||
import net.unix
|
||||
import os
|
||||
import freeflowuniverse.herolib.ui.console
|
||||
|
||||
pub struct RPCServer {
|
||||
mut:
|
||||
listener &unix.StreamListener
|
||||
socket_path string
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct RPCServerArgs {
|
||||
pub mut:
|
||||
socket_path string = '/tmp/heromodels'
|
||||
}
|
||||
|
||||
pub fn new_rpc_server(args RPCServerArgs) !&RPCServer {
|
||||
// Remove existing socket file if it exists
|
||||
if os.exists(args.socket_path) {
|
||||
os.rm(args.socket_path)!
|
||||
}
|
||||
|
||||
listener := unix.listen_stream(args.socket_path, unix.ListenOptions{})!
|
||||
|
||||
return &RPCServer{
|
||||
listener: listener
|
||||
socket_path: args.socket_path
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut server RPCServer) start() ! {
|
||||
console.print_header('Starting HeroModels OpenRPC Server on ${server.socket_path}')
|
||||
|
||||
for {
|
||||
mut conn := server.listener.accept()!
|
||||
spawn server.handle_connection(mut conn)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut server RPCServer) close() ! {
|
||||
server.listener.close()!
|
||||
if os.exists(server.socket_path) {
|
||||
os.rm(server.socket_path)!
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut server RPCServer) handle_connection(mut conn unix.StreamConn) {
|
||||
defer {
|
||||
conn.close() or { console.print_stderr('Error closing connection: ${err}') }
|
||||
}
|
||||
|
||||
for {
|
||||
// Read JSON-RPC request
|
||||
mut buffer := []u8{len: 4096}
|
||||
bytes_read := conn.read(mut buffer) or {
|
||||
console.print_debug('Connection closed or error reading: ${err}')
|
||||
break
|
||||
}
|
||||
|
||||
if bytes_read == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
request_data := buffer[..bytes_read].bytestr()
|
||||
console.print_debug('Received request: ${request_data}')
|
||||
|
||||
// Process the JSON-RPC request
|
||||
response := server.process_request(request_data) or {
|
||||
server.create_error_response(-32603, 'Internal error: ${err}', json2.null)
|
||||
}
|
||||
|
||||
// Send response
|
||||
conn.write_string(response) or {
|
||||
console.print_stderr('Error writing response: ${err}')
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut server RPCServer) process_request(request_data string) !string {
|
||||
// Parse JSON-RPC request
|
||||
request := json2.decode[JsonRpcRequest](request_data)!
|
||||
|
||||
// Route to appropriate method
|
||||
result := match request.method {
|
||||
'comment_get' {
|
||||
server.comment_get(request.params)!
|
||||
}
|
||||
'comment_set' {
|
||||
server.comment_set(request.params)!
|
||||
}
|
||||
'comment_delete' {
|
||||
server.comment_delete(request.params)!
|
||||
}
|
||||
'comment_list' {
|
||||
server.comment_list()!
|
||||
}
|
||||
'discover' {
|
||||
server.discover()!
|
||||
}
|
||||
else {
|
||||
return server.create_error_response(-32601, 'Method not found', request.id)
|
||||
}
|
||||
}
|
||||
|
||||
return server.create_success_response(result, request.id)
|
||||
}
|
||||
|
||||
fn (mut server RPCServer) create_success_response(result json2.Any, id json2.Any) string {
|
||||
response := JsonRpcResponse{
|
||||
jsonrpc: '2.0'
|
||||
result: result
|
||||
id: id
|
||||
}
|
||||
return json2.encode(response)
|
||||
}
|
||||
|
||||
fn (mut server RPCServer) create_error_response(code int, message string, id json2.Any) string {
|
||||
error := JsonRpcError{
|
||||
code: code
|
||||
message: message
|
||||
data: json2.null
|
||||
}
|
||||
response := JsonRpcResponse{
|
||||
jsonrpc: '2.0'
|
||||
error: error
|
||||
id: id
|
||||
}
|
||||
return json2.encode(response)
|
||||
}
|
||||
44
lib/hero/heromodels/openrpc/types.v
Normal file
44
lib/hero/heromodels/openrpc/types.v
Normal file
@@ -0,0 +1,44 @@
|
||||
module openrpc
|
||||
|
||||
import x.json2
|
||||
|
||||
// JSON-RPC 2.0 request structure
|
||||
pub struct JsonRpcRequest {
|
||||
pub:
|
||||
jsonrpc string = '2.0'
|
||||
method string
|
||||
params json2.Any
|
||||
id json2.Any
|
||||
}
|
||||
|
||||
// JSON-RPC 2.0 response structure
|
||||
pub struct JsonRpcResponse {
|
||||
pub:
|
||||
jsonrpc string = '2.0'
|
||||
result json2.Any
|
||||
error ?JsonRpcError
|
||||
id json2.Any
|
||||
}
|
||||
|
||||
// JSON-RPC 2.0 error structure
|
||||
pub struct JsonRpcError {
|
||||
pub:
|
||||
code int
|
||||
message string
|
||||
data json2.Any
|
||||
}
|
||||
|
||||
// Comment-specific argument structures
|
||||
@[params]
|
||||
pub struct CommentGetArgs {
|
||||
pub mut:
|
||||
id ?u32
|
||||
author ?u32
|
||||
parent ?u32
|
||||
}
|
||||
|
||||
@[params]
|
||||
pub struct CommentDeleteArgs {
|
||||
pub mut:
|
||||
id u32
|
||||
}
|
||||
Reference in New Issue
Block a user