refactor: Improve data decoding and handler logic

- Add strconv for string number parsing
- Update decode_int and decode_u32 for string/JSON numbers
- Refactor model handlers to use .new(args) for object creation
- Remove unnecessary jsonrpc.new_request calls
- Update Profile struct and ProfileArg for clarity
This commit is contained in:
Mahmoud-Emad
2025-09-24 14:34:42 +03:00
parent 6800631ead
commit 78fce909a8
14 changed files with 141 additions and 118 deletions

View File

@@ -2,13 +2,32 @@ module db
import x.json2
import json
import strconv
pub fn decode_int(data string) !int {
return json2.decode[int](data) or { return error('Failed to decode int: ${data}') }
// Try JSON decode first (for proper JSON numbers like "123")
if result := json2.decode[int](data) {
return result
}
// If that fails, try parsing as a string number (for quoted strings like "\"123\"")
trimmed := data.trim_space().trim('"')
parsed_int := strconv.parse_int(trimmed, 10, 32) or {
return error('Failed to decode int: ${data}')
}
return int(parsed_int)
}
pub fn decode_u32(data string) !u32 {
return json2.decode[u32](data) or { return error('Failed to decode u32: ${data}') }
// Try JSON decode first (for proper JSON numbers like "123")
if result := json2.decode[u32](data) {
return result
}
// If that fails, try parsing as a string number (for quoted strings like "\"123\"")
trimmed := data.trim_space().trim('"')
parsed_uint := strconv.parse_uint(trimmed, 10, 32) or {
return error('Failed to decode u32: ${data}')
}
return u32(parsed_uint)
}
pub fn decode_bool(data string) !bool {

View File

@@ -150,7 +150,8 @@ pub fn calendar_handle(mut f ModelsFactory, rpcid int, servercontext map[string]
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Calendar](params)!
args := db.decode_generic[CalendarArg](params)!
mut o := f.calendar.new(args)!
o = f.calendar.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -168,9 +169,8 @@ pub fn calendar_handle(mut f ModelsFactory, rpcid int, servercontext map[string]
}
}
'list' {
req := jsonrpc.new_request(method, '') // no params
res := f.calendar.list()!
return new_response(req.id, json.encode(res))
return new_response(rpcid, json.encode(res))
}
else {
console.print_stderr('Method not found on calendar: ${method}')

View File

@@ -457,7 +457,8 @@ pub fn calendar_event_handle(mut f ModelsFactory, rpcid int, servercontext map[s
return new_response(rpcid, json.encode_pretty(res))
}
'set' {
mut o := db.decode_generic[CalendarEvent](params)!
args := db.decode_generic[CalendarEventArg](params)!
mut o := f.calendar_event.new(args)!
o = f.calendar_event.set(o)!
return new_response_int(rpcid, int(o.id))
}

View File

@@ -3,7 +3,7 @@ module heromodels
import freeflowuniverse.herolib.data.encoder
import freeflowuniverse.herolib.data.ourtime
import freeflowuniverse.herolib.hero.db
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_ok, new_response_true, new_response_int }
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_int, new_response_ok, new_response_true }
import freeflowuniverse.herolib.hero.user { UserRef }
import json
@@ -15,7 +15,7 @@ pub mut:
chat_type ChatType
last_activity i64
is_archived bool
group_id u32 //group linked to this chat group
group_id u32 // group linked to this chat group
}
pub enum ChatType {
@@ -162,7 +162,6 @@ pub fn (mut self DBChatGroup) list() ![]ChatGroup {
return self.db.list[ChatGroup]()!.map(self.get(it)!)
}
pub fn chat_group_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
match method {
'get' {
@@ -171,7 +170,8 @@ pub fn chat_group_handle(mut f ModelsFactory, rpcid int, servercontext map[strin
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[ChatGroup](params)!
args := db.decode_generic[ChatGroupArg](params)!
mut o := f.chat_group.new(args)!
o = f.chat_group.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -189,9 +189,8 @@ pub fn chat_group_handle(mut f ModelsFactory, rpcid int, servercontext map[strin
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.chat_group.list()!
return new_response(req.id, json.encode(res))
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,
@@ -200,4 +199,4 @@ pub fn chat_group_handle(mut f ModelsFactory, rpcid int, servercontext map[strin
)
}
}
}
}

View File

@@ -3,7 +3,7 @@ module heromodels
import freeflowuniverse.herolib.data.encoder
import freeflowuniverse.herolib.data.ourtime
import freeflowuniverse.herolib.hero.db
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_ok, new_response_true, new_response_int }
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_int, new_response_ok, new_response_true }
import freeflowuniverse.herolib.hero.user { UserRef }
import json
@@ -262,7 +262,6 @@ pub fn (mut self DBChatMessage) list() ![]ChatMessage {
return self.db.list[ChatMessage]()!.map(self.get(it)!)
}
pub fn chat_message_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
match method {
'get' {
@@ -271,7 +270,8 @@ pub fn chat_message_handle(mut f ModelsFactory, rpcid int, servercontext map[str
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[ChatMessage](params)!
args := db.decode_generic[ChatMessageArg](params)!
mut o := f.chat_message.new(args)!
o = f.chat_message.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -289,9 +289,8 @@ pub fn chat_message_handle(mut f ModelsFactory, rpcid int, servercontext map[str
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.chat_message.list()!
return new_response(req.id, json.encode(res))
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,
@@ -300,4 +299,4 @@ pub fn chat_message_handle(mut f ModelsFactory, rpcid int, servercontext map[str
)
}
}
}
}

View File

@@ -203,7 +203,8 @@ pub fn contact_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Contact](params)!
args := db.decode_generic[ContactArg](params)!
mut o := f.contact.new(args)!
o = f.contact.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -221,9 +222,9 @@ pub fn contact_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.contact.list(ContactListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[ContactListArg](params)!
res := f.contact.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -258,7 +258,8 @@ pub fn group_handle(mut f ModelsFactory, rpcid int, servercontext map[string]str
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Group](params)!
args := db.decode_generic[GroupArg](params)!
mut o := f.group.new(args)!
o = f.group.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -276,9 +277,9 @@ pub fn group_handle(mut f ModelsFactory, rpcid int, servercontext map[string]str
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.group.list()!
return new_response(req.id, json.encode(res))
args := db.decode_generic[GroupListArg](params)!
res := f.group.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -232,7 +232,8 @@ pub fn message_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Message](params)!
args := db.decode_generic[MessageArg](params)!
mut o := f.messages.new(args)!
o = f.messages.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -250,9 +251,9 @@ pub fn message_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.messages.list(MessageListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[MessageListArg](params)!
res := f.messages.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -292,7 +292,8 @@ pub fn planning_handle(mut f ModelsFactory, rpcid int, servercontext map[string]
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Planning](params)!
args := db.decode_generic[PlanningArg](params)!
mut o := f.planning.new(args)!
o = f.planning.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -310,9 +311,9 @@ pub fn planning_handle(mut f ModelsFactory, rpcid int, servercontext map[string]
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.planning.list(PlanningListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[PlanningListArg](params)!
res := f.planning.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -3,7 +3,7 @@ module heromodels
import freeflowuniverse.herolib.data.encoder
import freeflowuniverse.herolib.data.ourtime
import freeflowuniverse.herolib.hero.db
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_ok, new_response_true, new_response_int }
import freeflowuniverse.herolib.schemas.jsonrpc { Response, new_error, new_response, new_response_false, new_response_int, new_response_ok, new_response_true }
import freeflowuniverse.herolib.hero.user { UserRef }
import json
@@ -11,13 +11,13 @@ import json
pub struct Profile {
db.Base
pub mut:
user_id u32 // a user can have more than one profile
summary string
user_id u32 // a user can have more than one profile
summary string
headline string
location string
industry string
// urls to profile pictures
picture_url string
picture_url string
background_image_url string
// contact info
email string
@@ -109,79 +109,77 @@ pub fn (self Profile) example(methodname string) (string, string) {
}
pub fn (self Profile) dump(mut e encoder.Encoder) ! {
e.add_u32(self.user_id)
e.add_string(self.summary)
e.add_string(self.headline)
e.add_string(self.location)
e.add_string(self.industry)
e.add_string(self.picture_url)
e.add_string(self.background_image_url)
e.add_string(self.email)
e.add_string(self.phone)
e.add_string(self.website)
e.add_string(json.encode_pretty(self.experience))
e.add_string(json.encode_pretty(self.education))
e.add_list_string(self.skills)
e.add_list_string(self.languages)
e.add_u32(self.user_id)
e.add_string(self.summary)
e.add_string(self.headline)
e.add_string(self.location)
e.add_string(self.industry)
e.add_string(self.picture_url)
e.add_string(self.background_image_url)
e.add_string(self.email)
e.add_string(self.phone)
e.add_string(self.website)
e.add_string(json.encode_pretty(self.experience))
e.add_string(json.encode_pretty(self.education))
e.add_list_string(self.skills)
e.add_list_string(self.languages)
}
fn (mut self DBProfile) load(mut o Profile, mut e encoder.Decoder) ! {
o.user_id = e.get_u32()!
o.summary = e.get_string()!
o.headline = e.get_string()!
o.location = e.get_string()!
o.industry = e.get_string()!
o.picture_url = e.get_string()!
o.background_image_url = e.get_string()!
o.email = e.get_string()!
o.phone = e.get_string()!
o.website = e.get_string()!
o.experience = json.decode([]Experience, e.get_string()!)!
o.education = json.decode([]Education, e.get_string()!)!
o.skills = e.get_list_string()!
o.languages = e.get_list_string()!
o.user_id = e.get_u32()!
o.summary = e.get_string()!
o.headline = e.get_string()!
o.location = e.get_string()!
o.industry = e.get_string()!
o.picture_url = e.get_string()!
o.background_image_url = e.get_string()!
o.email = e.get_string()!
o.phone = e.get_string()!
o.website = e.get_string()!
o.experience = json.decode([]Experience, e.get_string()!)!
o.education = json.decode([]Education, e.get_string()!)!
o.skills = e.get_list_string()!
o.languages = e.get_list_string()!
}
@[params]
pub struct ProfileArg {
pub mut:
name string
description string
user_id u32 // a user can have more than one profile
summary string
headline string
location string
industry string
picture_url string
name string
description string
user_id u32 // a user can have more than one profile
summary string
headline string
location string
industry string
picture_url string
background_image_url string
email string
phone string
website string
experience []Experience
education []Education
skills []string
languages []string
email string
phone string
website string
experience []Experience
education []Education
skills []string
languages []string
}
// get new profile, not from the DB
pub fn (mut self DBProfile) new(args ProfileArg) !Profile {
mut o := Profile{
user_id: args.user_id
summary: args.summary
headline: args.headline
location: args.location
industry: args.industry
picture_url: args.picture_url
user_id: args.user_id
summary: args.summary
headline: args.headline
location: args.location
industry: args.industry
picture_url: args.picture_url
background_image_url: args.background_image_url
email: args.email
phone: args.phone
website: args.website
experience: args.experience
education: args.education
skills: args.skills
languages: args.languages
email: args.email
phone: args.phone
website: args.website
experience: args.experience
education: args.education
skills: args.skills
languages: args.languages
}
// Set base fields
@@ -227,8 +225,8 @@ pub fn profile_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
}
'set' {
mut o := db.decode_generic[Profile](params)!
o=f.profile.set(o)!
return new_response_int(rpcid,int(o.id))
o = f.profile.set(o)!
return new_response_int(rpcid, int(o.id))
}
'delete' {
id := db.decode_u32(params)!
@@ -244,9 +242,8 @@ pub fn profile_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
}
}
'list' {
req := jsonrpc.new_request(method, '') // no params
res := f.profile.list()!
return new_response(req.id, json.encode_pretty(res))
return new_response(rpcid, json.encode_pretty(res))
}
else {
println('Method not found on profile: ${method}')
@@ -257,4 +254,4 @@ pub fn profile_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
)
}
}
}
}

View File

@@ -280,7 +280,8 @@ pub fn project_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[Project](params)!
args := db.decode_generic[ProjectArg](params)!
mut o := f.project.new(args)!
o = f.project.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -298,9 +299,9 @@ pub fn project_handle(mut f ModelsFactory, rpcid int, servercontext map[string]s
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.project.list(ProjectListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[ProjectListArg](params)!
res := f.project.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -324,7 +324,8 @@ pub fn project_issue_handle(mut f ModelsFactory, rpcid int, servercontext map[st
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[ProjectIssue](params)!
args := db.decode_generic[ProjectIssueArg](params)!
mut o := f.project_issue.new(args)!
o = f.project_issue.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -342,9 +343,9 @@ pub fn project_issue_handle(mut f ModelsFactory, rpcid int, servercontext map[st
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.project_issue.list()!
return new_response(req.id, json.encode(res))
args := db.decode_generic[ProjectIssueListArg](params)!
res := f.project_issue.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -298,7 +298,8 @@ pub fn registration_desk_handle(mut f ModelsFactory, rpcid int, servercontext ma
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[RegistrationDesk](params)!
args := db.decode_generic[RegistrationDeskArg](params)!
mut o := f.registration_desk.new(args)!
o = f.registration_desk.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -316,9 +317,9 @@ pub fn registration_desk_handle(mut f ModelsFactory, rpcid int, servercontext ma
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.registration_desk.list(RegistrationDeskListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[RegistrationDeskListArg](params)!
res := f.registration_desk.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,

View File

@@ -186,7 +186,8 @@ pub fn user_handle(mut f ModelsFactory, rpcid int, servercontext map[string]stri
return new_response(rpcid, json.encode(res))
}
'set' {
mut o := db.decode_generic[User](params)!
args := db.decode_generic[UserArg](params)!
mut o := f.user.new(args)!
o = f.user.set(o)!
return new_response_int(rpcid, int(o.id))
}
@@ -204,9 +205,9 @@ pub fn user_handle(mut f ModelsFactory, rpcid int, servercontext map[string]stri
}
}
'list' {
req := jsonrpc.new_request(method, '')
res := f.user.list(UserListArg{})!
return new_response(req.id, json.encode(res))
args := db.decode_generic[UserListArg](params)!
res := f.user.list(args)!
return new_response(rpcid, json.encode(res))
}
else {
return new_error(rpcid,