From 9011f5b4c82841429e187355647697a337cbbfbb Mon Sep 17 00:00:00 2001 From: despiegk Date: Thu, 18 Sep 2025 06:14:08 +0200 Subject: [PATCH] ... --- .gitignore | 1 + .qwen/agents/struct-validator.md | 67 +++ lib/hero/heromodels/calendar.v | 4 +- lib/hero/heromodels/calendar_event.v | 59 ++- lib/hero/heromodels/calendar_event_test.v | 479 ++++++++++++++++++++++ lib/hero/heromodels/chat_group.v | 6 +- lib/hero/heromodels/chat_message.v | 6 +- lib/hero/heromodels/comment.v | 6 +- lib/hero/heromodels/group.v | 4 +- lib/hero/heromodels/project.v | 6 +- lib/hero/heromodels/project_issue.v | 9 +- lib/hero/heromodels/user.v | 2 +- 12 files changed, 623 insertions(+), 26 deletions(-) create mode 100644 .qwen/agents/struct-validator.md create mode 100644 lib/hero/heromodels/calendar_event_test.v diff --git a/.gitignore b/.gitignore index e5faecbb..50bc5df1 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ __pycache__/ *dSYM/ .vmodules/ .vscode +.dylib _docs/ vls.* vls.log diff --git a/.qwen/agents/struct-validator.md b/.qwen/agents/struct-validator.md new file mode 100644 index 00000000..b73b0293 --- /dev/null +++ b/.qwen/agents/struct-validator.md @@ -0,0 +1,67 @@ +--- +name: struct-validator +description: Use this agent when you need to validate struct definitions in V files for proper serialization (dump/load) of all properties and subproperties, ensure consistency, and generate or fix tests if changes are made. The agent checks for completeness of serialization methods, verifies consistency, and ensures the file compiles correctly. +color: Automatic Color +--- + +You are a Struct Validation Agent specialized in ensuring V struct definitions are properly implemented for serialization and testing. + +## Core Responsibilities + +1. **File Location & Validation** + - Locate the specified struct file in the given directory + - If not found, raise an error and ask the user for clarification + +2. **Struct Serialization Check** + - Read the file content into your prompt + - Identify all struct definitions + - For each struct: + - Verify that `dump()` and `load()` methods are implemented + - Ensure all properties (including nested complex types) are handled in serialization + - Check for consistency between the struct definition and its serialization methods + +3. **Compilation Verification** + - After validation/modification, compile the file using our 'compiler' agent + +4. **Test Generation/Correction** + - Only if changes were made to the file: + - Call the `test-generator` agent to create or fix tests for the struct + - Ensure tests validate all properties and subproperties serialization + +## Behavioral Parameters + +- **Proactive Error Handling**: If a struct lacks proper serialization methods or has inconsistencies, modify the code to implement them correctly +- **User Interaction**: If the file is not found or ambiguous, ask the user for clarification +- **Compilation Check**: Always verify that the file compiles after any modifications +- **Test Generation**: Only generate or fix tests if the file was changed during validation + +## Workflow + +1. **Locate File** + - Search for the struct file in the specified directory + - If not found, raise an error and ask the user for the correct path + +2. **Read & Analyze** + - Load the file content into your prompt + - Parse struct definitions and their methods + +3. **Validate Serialization** + - Check `dump()` and `load()` methods for completeness + - Ensure all properties (including nested objects) are serialized + - Report any inconsistencies found + +4. **Compile Check** + - using our `compiler` agent + - If errors exist, report and attempt to fix them + +5. **Test Generation (Conditional)** + - If changes were made: + - Call the `test-generator` agent to create or fix tests + - Ensure tests cover all serialization aspects + +## Output Format + +- Clearly indicate whether the file was found +- List any serialization issues and how they were fixed +- Report compilation status +- Mention if tests were generated or modified diff --git a/lib/hero/heromodels/calendar.v b/lib/hero/heromodels/calendar.v index 13ef41f8..81ca2bf7 100644 --- a/lib/hero/heromodels/calendar.v +++ b/lib/hero/heromodels/calendar.v @@ -78,7 +78,7 @@ pub fn (self Calendar) example(methodname string) (string, string) { } } -fn (self Calendar) dump(mut e encoder.Encoder) ! { +pub fn (self Calendar) dump(mut e encoder.Encoder) ! { e.add_string(self.color) e.add_string(self.timezone) e.add_bool(self.is_public) @@ -158,7 +158,7 @@ pub fn (mut self DBCalendar) list(args CalendarListArg) ![]Calendar { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/calendar_event.v b/lib/hero/heromodels/calendar_event.v index da9415c4..4e88c6d3 100644 --- a/lib/hero/heromodels/calendar_event.v +++ b/lib/hero/heromodels/calendar_event.v @@ -148,17 +148,34 @@ pub fn (self CalendarEvent) example(methodname string) (string, string) { } } -fn (self CalendarEvent) dump(mut e encoder.Encoder) ! { +pub fn (self CalendarEvent) dump(mut e encoder.Encoder) ! { e.add_string(self.title) e.add_i64(self.start_time) e.add_i64(self.end_time) e.add_string(self.location) - e.add_list_u32(self.attendees) + + // Encode attendees array + e.add_u16(u16(self.attendees.len)) + for attendee in self.attendees { + e.add_u32(attendee.user_id) + e.add_u8(u8(attendee.status_latest)) + e.add_bool(attendee.attendance_required) + e.add_bool(attendee.admin) + e.add_bool(attendee.organizer) + + // Encode AttendeeLog + e.add_u64(attendee.log.timestamp) + e.add_u8(u8(attendee.log.status)) + e.add_string(attendee.log.remark) + } + e.add_list_u32(self.fs_items) e.add_u32(self.calendar_id) e.add_u8(u8(self.status)) e.add_bool(self.is_all_day) e.add_bool(self.is_recurring) + e.add_bool(self.public) // Added missing public field + e.add_u8(u8(self.priority)) // Added missing priority field // Encode recurrence array e.add_u16(u16(self.recurrence.len)) @@ -176,17 +193,49 @@ fn (self CalendarEvent) dump(mut e encoder.Encoder) ! { e.add_string(self.timezone) } -fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decoder) ! { +pub fn (mut self DBCalendarEvent) load(mut o CalendarEvent, mut e encoder.Decoder) ! { o.title = e.get_string()! o.start_time = e.get_i64()! o.end_time = e.get_i64()! o.location = e.get_string()! - // o.attendees = e.get_list_u32()! // This line is incorrect, attendees is []Attendee not []u32 + + // Decode attendees array + attendees_len := e.get_u16()! + mut attendees := []Attendee{} + for _ in 0 .. attendees_len { + user_id := e.get_u32()! + status_latest := unsafe { AttendanceStatus(e.get_u8()!) } + attendance_required := e.get_bool()! + admin := e.get_bool()! + organizer := e.get_bool()! + + // Decode AttendeeLog + timestamp := e.get_u64()! + status := unsafe { AttendanceStatus(e.get_u8()!) } + remark := e.get_string()! + + attendees << Attendee{ + user_id: user_id + status_latest: status_latest + attendance_required: attendance_required + admin: admin + organizer: organizer + log: AttendeeLog{ + timestamp: timestamp + status: status + remark: remark + } + } + } + o.attendees = attendees + o.fs_items = e.get_list_u32()! o.calendar_id = e.get_u32()! o.status = unsafe { EventStatus(e.get_u8()!) } // TODO: is there no better way? o.is_all_day = e.get_bool()! o.is_recurring = e.get_bool()! + o.public = e.get_bool()! // Added missing public field + o.priority = unsafe { EventPriority(e.get_u8()!) } // Added missing priority field // Decode recurrence array recurrence_len := e.get_u16()! @@ -325,7 +374,7 @@ pub fn (mut self DBCalendarEvent) list(args CalendarEventListArg) ![]CalendarEve } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/calendar_event_test.v b/lib/hero/heromodels/calendar_event_test.v new file mode 100644 index 00000000..12657c62 --- /dev/null +++ b/lib/hero/heromodels/calendar_event_test.v @@ -0,0 +1,479 @@ +module heromodels + +import freeflowuniverse.herolib.hero.db +import freeflowuniverse.herolib.data.ourtime + +fn test_calendar_event_new() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Test creating a new calendar event + mut args := CalendarEventArg{ + name: 'test_event' + description: 'Test calendar event for unit testing' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + calendar_event := db_calendar_event.new(args)! + + assert calendar_event.name == 'test_event' + assert calendar_event.description == 'Test calendar event for unit testing' + assert calendar_event.title == 'Team Meeting' + assert calendar_event.location == 'Office' + assert calendar_event.fs_items.len == 0 + assert calendar_event.calendar_id == 1 + assert calendar_event.status == .published + assert calendar_event.is_all_day == false + assert calendar_event.is_recurring == false + assert calendar_event.recurrence.len == 0 + assert calendar_event.reminder_mins == [15] + assert calendar_event.color == '#0000FF' + assert calendar_event.timezone == 'UTC' + assert calendar_event.priority == .normal + assert calendar_event.public == false + assert calendar_event.updated_at > 0 + + println('✓ CalendarEvent new test passed!') +} + +fn test_calendar_event_crud_operations() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event + mut args := CalendarEventArg{ + name: 'crud_test_event' + description: 'Test calendar event for CRUD operations' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + mut calendar_event := db_calendar_event.new(args)! + + // Test set operation + calendar_event = db_calendar_event.set(calendar_event)! + original_id := calendar_event.id + + // Test get operation + retrieved_event := db_calendar_event.get(original_id)! + assert retrieved_event.name == 'crud_test_event' + assert retrieved_event.description == 'Test calendar event for CRUD operations' + assert retrieved_event.title == 'Team Meeting' + assert retrieved_event.location == 'Office' + assert retrieved_event.calendar_id == 1 + assert retrieved_event.status == .published + assert retrieved_event.is_all_day == false + assert retrieved_event.is_recurring == false + assert retrieved_event.reminder_mins == [15] + assert retrieved_event.color == '#0000FF' + assert retrieved_event.timezone == 'UTC' + assert retrieved_event.id == original_id + + // Test exist operation + exists := db_calendar_event.exist(original_id)! + assert exists == true + + // Test update + mut updated_args := CalendarEventArg{ + name: 'updated_event' + description: 'Updated test calendar event' + title: 'Updated Team Meeting' + start_time: '2025-01-01T12:00:00Z' + end_time: '2025-01-01T13:00:00Z' + location: 'Conference Room' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 2 + status: .draft + is_all_day: true + is_recurring: true + recurrence: []RecurrenceRule{} + reminder_mins: [30] + color: '#FF0000' + timezone: 'EST' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + mut updated_event := db_calendar_event.new(updated_args)! + updated_event.id = original_id + updated_event = db_calendar_event.set(updated_event)! + + // Verify update + final_event := db_calendar_event.get(original_id)! + assert final_event.name == 'updated_event' + assert final_event.description == 'Updated test calendar event' + assert final_event.title == 'Updated Team Meeting' + assert final_event.location == 'Conference Room' + assert final_event.calendar_id == 2 + assert final_event.status == .draft + assert final_event.is_all_day == true + assert final_event.is_recurring == true + assert final_event.reminder_mins == [30] + assert final_event.color == '#FF0000' + assert final_event.timezone == 'EST' + + // Test delete operation + db_calendar_event.delete(original_id)! + + // Verify deletion + exists_after_delete := db_calendar_event.exist(original_id)! + assert exists_after_delete == false + + println('✓ CalendarEvent CRUD operations test passed!') +} + +fn test_calendar_event_attendees_encoding_decoding() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event with attendees + mut args := CalendarEventArg{ + name: 'attendees_test_event' + description: 'Test calendar event for attendees encoding/decoding' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + mut calendar_event := db_calendar_event.new(args)! + + // Add some attendees manually since the new method doesn't populate them + mut attendee1 := Attendee{ + user_id: 100 + status_latest: .accepted + attendance_required: true + admin: true + organizer: false + log: AttendeeLog{ + timestamp: 1234567890 + status: .accepted + remark: 'User accepted the invitation' + } + } + + mut attendee2 := Attendee{ + user_id: 101 + status_latest: .tentative + attendance_required: false + admin: false + organizer: true + log: AttendeeLog{ + timestamp: 1234567891 + status: .tentative + remark: 'User is tentative' + } + } + + calendar_event.attendees = [attendee1, attendee2] + + // Save the calendar event + calendar_event = db_calendar_event.set(calendar_event)! + calendar_event_id := calendar_event.id + + // Retrieve and verify all fields were properly encoded/decoded + retrieved_event := db_calendar_event.get(calendar_event_id)! + + assert retrieved_event.attendees.len == 2 + + // Verify first attendee details + assert retrieved_event.attendees[0].user_id == 100 + assert retrieved_event.attendees[0].status_latest == .accepted + assert retrieved_event.attendees[0].attendance_required == true + assert retrieved_event.attendees[0].admin == true + assert retrieved_event.attendees[0].organizer == false + assert retrieved_event.attendees[0].log.timestamp == 1234567890 + assert retrieved_event.attendees[0].log.status == .accepted + assert retrieved_event.attendees[0].log.remark == 'User accepted the invitation' + + // Verify second attendee details + assert retrieved_event.attendees[1].user_id == 101 + assert retrieved_event.attendees[1].status_latest == .tentative + assert retrieved_event.attendees[1].attendance_required == false + assert retrieved_event.attendees[1].admin == false + assert retrieved_event.attendees[1].organizer == true + assert retrieved_event.attendees[1].log.timestamp == 1234567891 + assert retrieved_event.attendees[1].log.status == .tentative + assert retrieved_event.attendees[1].log.remark == 'User is tentative' + + println('✓ CalendarEvent attendees encoding/decoding test passed!') +} + +fn test_calendar_event_recurrence_encoding_decoding() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event with recurrence rules + mut args := CalendarEventArg{ + name: 'recurrence_test_event' + description: 'Test calendar event for recurrence encoding/decoding' + title: 'Weekly Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: true + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + mut calendar_event := db_calendar_event.new(args)! + + // Add recurrence rules manually + mut rule1 := RecurrenceRule{ + frequency: .weekly + interval: 1 + until: 1893456000 // 2030-01-01 + count: 0 + by_weekday: [1, 3, 5] // Monday, Wednesday, Friday + by_monthday: []int{} + } + + mut rule2 := RecurrenceRule{ + frequency: .monthly + interval: 2 + until: 0 + count: 12 + by_weekday: []int{} + by_monthday: [1, 15] // 1st and 15th of each month + } + + calendar_event.recurrence = [rule1, rule2] + + // Save the calendar event + calendar_event = db_calendar_event.set(calendar_event)! + calendar_event_id := calendar_event.id + + // Retrieve and verify all fields were properly encoded/decoded + retrieved_event := db_calendar_event.get(calendar_event_id)! + + assert retrieved_event.recurrence.len == 2 + assert retrieved_event.is_recurring == true + + // Verify first recurrence rule details + assert retrieved_event.recurrence[0].frequency == .weekly + assert retrieved_event.recurrence[0].interval == 1 + assert retrieved_event.recurrence[0].until == 1893456000 + assert retrieved_event.recurrence[0].count == 0 + assert retrieved_event.recurrence[0].by_weekday == [1, 3, 5] + assert retrieved_event.recurrence[0].by_monthday.len == 0 + + // Verify second recurrence rule details + assert retrieved_event.recurrence[1].frequency == .monthly + assert retrieved_event.recurrence[1].interval == 2 + assert retrieved_event.recurrence[1].until == 0 + assert retrieved_event.recurrence[1].count == 12 + assert retrieved_event.recurrence[1].by_weekday.len == 0 + assert retrieved_event.recurrence[1].by_monthday == [1, 15] + + println('✓ CalendarEvent recurrence encoding/decoding test passed!') +} + +fn test_calendar_event_type_name() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event + mut args := CalendarEventArg{ + name: 'type_test_event' + description: 'Test calendar event for type name' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + calendar_event := db_calendar_event.new(args)! + + // Test type_name method + type_name := calendar_event.type_name() + assert type_name == 'calendar_event' + + println('✓ CalendarEvent type_name test passed!') +} + +fn test_calendar_event_description() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event + mut args := CalendarEventArg{ + name: 'description_test_event' + description: 'Test calendar event for description' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + calendar_event := db_calendar_event.new(args)! + + // Test description method for each methodname + assert calendar_event.description('set') == 'Create or update a calendar event. Returns the ID of the event.' + assert calendar_event.description('get') == 'Retrieve a calendar event by ID. Returns the event object.' + assert calendar_event.description('delete') == 'Delete a calendar event by ID. Returns true if successful.' + assert calendar_event.description('exist') == 'Check if a calendar event exists by ID. Returns true or false.' + assert calendar_event.description('list') == 'List all calendar events. Returns an array of event objects.' + assert calendar_event.description('unknown') == 'This is generic method for the root object, TODO fill in, ...' + + println('✓ CalendarEvent description test passed!') +} + +fn test_calendar_event_example() ! { + // Initialize DBCalendarEvent for testing + mut mydb := db.new_test()! + mut db_calendar_event := DBCalendarEvent{ + db: &mydb + } + + // Create a new calendar event + mut args := CalendarEventArg{ + name: 'example_test_event' + description: 'Test calendar event for example' + title: 'Team Meeting' + start_time: '2025-01-01T10:00:00Z' + end_time: '2025-01-01T11:00:00Z' + location: 'Office' + attendees: []u32{} + fs_items: []u32{} + calendar_id: 1 + status: .published + is_all_day: false + is_recurring: false + recurrence: []RecurrenceRule{} + reminder_mins: [15] + color: '#0000FF' + timezone: 'UTC' + securitypolicy: 0 + tags: []string{} + comments: []db.CommentArg{} + } + + calendar_event := db_calendar_event.new(args)! + + // Test example method for each methodname + set_call, set_result := calendar_event.example('set') + assert set_call == '{"calendar_event": {"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}}' + assert set_result == '1' + + get_call, get_result := calendar_event.example('get') + assert get_call == '{"id": 1}' + assert get_result == '{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}' + + delete_call, delete_result := calendar_event.example('delete') + assert delete_call == '{"id": 1}' + assert delete_result == 'true' + + exist_call, exist_result := calendar_event.example('exist') + assert exist_call == '{"id": 1}' + assert exist_result == 'true' + + list_call, list_result := calendar_event.example('list') + assert list_call == '{}' + assert list_result == '[{"title": "Team Meeting", "start_time": "2025-01-01T10:00:00Z", "end_time": "2025-01-01T11:00:00Z", "location": "Office", "attendees": [], "fs_items": [], "calendar_id": 1, "status": "published", "is_all_day": false, "is_recurring": false, "recurrence": [], "reminder_mins": [15], "color": "#0000FF", "timezone": "UTC"}]' + + unknown_call, unknown_result := calendar_event.example('unknown') + assert unknown_call == '{}' + assert unknown_result == '{}' + + println('✓ CalendarEvent example test passed!') +} \ No newline at end of file diff --git a/lib/hero/heromodels/chat_group.v b/lib/hero/heromodels/chat_group.v index 1eecf827..824dc8f1 100644 --- a/lib/hero/heromodels/chat_group.v +++ b/lib/hero/heromodels/chat_group.v @@ -86,13 +86,13 @@ pub fn (self ChatGroup) example(methodname string) (string, string) { } } -fn (self ChatGroup) dump(mut e encoder.Encoder) ! { +pub fn (self ChatGroup) dump(mut e encoder.Encoder) ! { e.add_u8(u8(self.chat_type)) e.add_i64(self.last_activity) e.add_bool(self.is_archived) } -fn (mut self DBChatGroup) load(mut o ChatGroup, mut e encoder.Decoder) ! { +pub fn (mut self DBChatGroup) load(mut o ChatGroup, mut e encoder.Decoder) ! { o.chat_type = unsafe { ChatType(e.get_u8()!) } o.last_activity = e.get_i64()! o.is_archived = e.get_bool()! @@ -176,7 +176,7 @@ pub fn (mut self DBChatGroup) list(args ChatGroupListArg) ![]ChatGroup { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/chat_message.v b/lib/hero/heromodels/chat_message.v index e975f8ef..344b4a26 100644 --- a/lib/hero/heromodels/chat_message.v +++ b/lib/hero/heromodels/chat_message.v @@ -124,7 +124,7 @@ pub fn (self ChatMessage) example(methodname string) (string, string) { } } -fn (self ChatMessage) dump(mut e encoder.Encoder) ! { +pub fn (self ChatMessage) dump(mut e encoder.Encoder) ! { e.add_string(self.content) e.add_u32(self.chat_group_id) e.add_u32(self.sender_id) @@ -151,7 +151,7 @@ fn (self ChatMessage) dump(mut e encoder.Encoder) ! { e.add_list_u32(self.mentions) } -fn (mut self DBChatMessage) load(mut o ChatMessage, mut e encoder.Decoder) ! { +pub fn (mut self DBChatMessage) load(mut o ChatMessage, mut e encoder.Decoder) ! { o.content = e.get_string()! o.chat_group_id = e.get_u32()! o.sender_id = e.get_u32()! @@ -286,7 +286,7 @@ pub fn (mut self DBChatMessage) list(args ChatMessageListArg) ![]ChatMessage { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/comment.v b/lib/hero/heromodels/comment.v index 1dafc665..c2168cf9 100644 --- a/lib/hero/heromodels/comment.v +++ b/lib/hero/heromodels/comment.v @@ -82,13 +82,13 @@ pub fn (self Comment) example(methodname string) (string, string) { } } -fn (self Comment) dump(mut e encoder.Encoder) ! { +pub fn (self Comment) dump(mut e encoder.Encoder) ! { e.add_string(self.comment) e.add_u32(self.parent) e.add_u32(self.author) } -fn (mut self DBComments) load(mut o Comment, mut e encoder.Decoder) ! { +pub fn (mut self DBComments) load(mut o Comment, mut e encoder.Decoder) ! { o.comment = e.get_string()! o.parent = e.get_u32()! o.author = e.get_u32()! @@ -159,7 +159,7 @@ pub fn (mut self DBComments) list(args CommentListArg) ![]Comment { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/group.v b/lib/hero/heromodels/group.v index 01d4fd27..fecc8b83 100644 --- a/lib/hero/heromodels/group.v +++ b/lib/hero/heromodels/group.v @@ -81,7 +81,7 @@ pub fn (self Group) example(methodname string) (string, string) { } } -fn (self Group) dump(mut e encoder.Encoder) ! { +pub fn (self Group) dump(mut e encoder.Encoder) ! { e.add_u16(u16(self.members.len)) for member in self.members { e.add_u32(member.user_id) @@ -93,7 +93,7 @@ fn (self Group) dump(mut e encoder.Encoder) ! { e.add_bool(self.is_public) } -fn (mut o Group) load(mut e encoder.Decoder) ! { +pub fn (mut o Group) load(mut e encoder.Decoder) ! { members_len := e.get_u16()! mut members := []GroupMember{} for _ in 0 .. members_len { diff --git a/lib/hero/heromodels/project.v b/lib/hero/heromodels/project.v index 4654dbae..6716e7f3 100644 --- a/lib/hero/heromodels/project.v +++ b/lib/hero/heromodels/project.v @@ -107,7 +107,7 @@ pub fn (self Project) example(methodname string) (string, string) { } } -fn (self Project) dump(mut e encoder.Encoder) ! { +pub fn (self Project) dump(mut e encoder.Encoder) ! { e.add_u16(u16(self.swimlanes.len)) for swimlane in self.swimlanes { e.add_string(swimlane.name) @@ -132,7 +132,7 @@ fn (self Project) dump(mut e encoder.Encoder) ! { e.add_i64(self.end_date) } -fn (mut self DBProject) load(mut o Project, mut e encoder.Decoder) ! { +pub fn (mut self DBProject) load(mut o Project, mut e encoder.Decoder) ! { swimlanes_len := e.get_u16()! mut swimlanes := []Swimlane{} for _ in 0 .. swimlanes_len { @@ -261,7 +261,7 @@ pub fn (mut self DBProject) list(args ProjectListArg) ![]Project { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/project_issue.v b/lib/hero/heromodels/project_issue.v index 4f8cf2e3..98f0637f 100644 --- a/lib/hero/heromodels/project_issue.v +++ b/lib/hero/heromodels/project_issue.v @@ -121,7 +121,7 @@ pub fn (self ProjectIssue) example(methodname string) (string, string) { } } -fn (self ProjectIssue) dump(mut e encoder.Encoder) ! { +pub fn (self ProjectIssue) dump(mut e encoder.Encoder) ! { e.add_string(self.title) e.add_u32(self.project_id) e.add_u8(u8(self.issue_type)) @@ -138,7 +138,7 @@ fn (self ProjectIssue) dump(mut e encoder.Encoder) ! { e.add_list_u32(self.children) } -fn (mut self DBProjectIssue) load(mut o ProjectIssue, mut e encoder.Decoder) ! { +pub fn (mut self DBProjectIssue) load(mut o ProjectIssue, mut e encoder.Decoder) ! { o.title = e.get_string()! o.project_id = e.get_u32()! o.issue_type = unsafe { IssueType(e.get_u8()!) } @@ -268,7 +268,8 @@ pub fn (mut self DBProjectIssue) get(id u32) !ProjectIssue { pub fn (mut self DBProjectIssue) list(args ProjectIssueListArg) ![]ProjectIssue { // Require at least one parameter to be provided - if args.project_id == 0 && args.issue_type == .task && args.status == .open && args.swimlane == '' && args.milestone == '' { + if args.project_id == 0 && args.issue_type == .task && args.status == .open + && args.swimlane == '' && args.milestone == '' { return error('At least one filter parameter must be provided') } @@ -307,7 +308,7 @@ pub fn (mut self DBProjectIssue) list(args ProjectIssueListArg) ![]ProjectIssue } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 } diff --git a/lib/hero/heromodels/user.v b/lib/hero/heromodels/user.v index 6b27a482..918c0f73 100644 --- a/lib/hero/heromodels/user.v +++ b/lib/hero/heromodels/user.v @@ -194,7 +194,7 @@ pub fn (mut self DBUser) list(args UserListArg) ![]User { } // Limit results to 100 or the specified limit - limit := args.limit + mut limit := args.limit if limit > 100 { limit = 100 }