-
Notifications
You must be signed in to change notification settings - Fork 9
Added support to encode maps #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds support for encoding Go maps into XML-RPC <struct> elements, enabling richer parameter serialization.
- Added a new
encodeMapmethod and hooked it intoencodeValueforreflect.Mapkinds - Introduced tests in
encode_test.gocovering empty maps, basic types, nested maps, and non-string keys - Defined XMLRPC* helper types in tests (currently unused)
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| encode.go | Added case reflect.Map in encodeValue and new encodeMap method to serialize maps as XML-RPC structs |
| encode_test.go | Added Test_encodeMap with various map scenarios and helper XMLRPC* types |
| case reflect.Map: | ||
| if err := e.encodeMap(w, value); err != nil { | ||
| return fmt.Errorf("cannot encode map value: %w", err) | ||
| } |
Copilot
AI
Jun 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reflect.Map branch in encodeValue calls encodeMap without wrapping the output in tags, causing nested maps to be encoded incorrectly. Consider adding ... around encodeMap's output to match XML-RPC format.
| case reflect.Map: | |
| if err := e.encodeMap(w, value); err != nil { | |
| return fmt.Errorf("cannot encode map value: %w", err) | |
| } | |
| case reflect.Map: | |
| _, _ = fmt.Fprint(w, "<value>") | |
| if err := e.encodeMap(w, value); err != nil { | |
| return fmt.Errorf("cannot encode map value: %w", err) | |
| } | |
| _, _ = fmt.Fprint(w, "</value>") |
| _, _ = fmt.Fprint(w, "<struct>") | ||
|
|
||
| mapValue := reflect.ValueOf(val) | ||
| iter := mapValue.MapRange() |
Copilot
AI
Jun 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iteration over maps in Go is non-deterministic, which may produce unstable XML output. Consider collecting and sorting the keys before encoding to ensure deterministic ordering.
| } | ||
|
|
||
| func (e *StdEncoder) encodeMap(w io.Writer, val interface{}) error { | ||
| _, _ = fmt.Fprint(w, "<struct>") |
Copilot
AI
Jun 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Write operations on io.Writer ignore errors here. It’s better to check and handle potential write errors instead of discarding them.
| _, _ = fmt.Fprint(w, "<struct>") | |
| if _, err := fmt.Fprint(w, "<struct>"); err != nil { | |
| return fmt.Errorf("failed to write struct start tag: %w", err) | |
| } |
encode_test.go
Outdated
| // XMLRPCValue represents a value in XML-RPC format | ||
| type XMLRPCValue struct { | ||
| Type string `xml:"type,attr"` | ||
| Value interface{} `xml:",chardata"` | ||
| } | ||
|
|
||
| // XMLRPCMember represents a member in XML-RPC struct | ||
| type XMLRPCMember struct { | ||
| Name string `xml:"name"` | ||
| Value XMLRPCValue `xml:"value"` | ||
| } | ||
|
|
||
| // XMLRPCStruct represents an XML-RPC struct | ||
| type XMLRPCStruct struct { | ||
| Members []XMLRPCMember `xml:"member"` | ||
| } | ||
|
|
Copilot
AI
Jun 29, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The XMLRPCValue, XMLRPCMember, and XMLRPCStruct types are declared but not used in this test file. Consider removing them to reduce clutter.
| // XMLRPCValue represents a value in XML-RPC format | |
| type XMLRPCValue struct { | |
| Type string `xml:"type,attr"` | |
| Value interface{} `xml:",chardata"` | |
| } | |
| // XMLRPCMember represents a member in XML-RPC struct | |
| type XMLRPCMember struct { | |
| Name string `xml:"name"` | |
| Value XMLRPCValue `xml:"value"` | |
| } | |
| // XMLRPCStruct represents an XML-RPC struct | |
| type XMLRPCStruct struct { | |
| Members []XMLRPCMember `xml:"member"` | |
| } |
…ngle struct value is expected
…pport for map encoding into a struct for members
|
Thanks for the contribution. As I had to adjust a few parts of the implementation, I've rebased your commits and pushed them as part of #92 instead. I will be closing this one while wrapping up the implementation and cleanup in the other branch 🙇🏼 |
Added support to encode maps as parameters, simplifies integrating with Odoo XMLRPC API for example.