Skip to content
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

Unmarshalling dict to struct #25

Open
lkramer opened this issue Jun 25, 2019 · 1 comment
Open

Unmarshalling dict to struct #25

lkramer opened this issue Jun 25, 2019 · 1 comment

Comments

@lkramer
Copy link

lkramer commented Jun 25, 2019

Hey, I noticed that the function UnmarshalDict have some behaviour around field names that may be undesirable (certainly is for my usecase).

The main issue is that when it looks up a fieldname it will make the first character uppercase if necessary, but no further changes. That means that if a dict field uses snake case, like this:
this_is_a_field the corresponding field in a struct would have to be:

type MyStruct struct {
    This_is_a_field int
}

Which both brake go conventions and is also confusing.
For my own purpose I rewrote the function the following way:

func unmarshalResponse(t kdb.Dict) (*OrderResponse, error) {              
    var (
        keys = t.Key.Data.([]string)
        vals = t.Value.Data.([]*kdb.K)                                    
        v    = new(OrderResponse)                                         
    )
    vv := reflect.Indirect(reflect.ValueOf(v))                            
    for i := range keys {
        val := vals[i].Data
        fv := vv.FieldByName(strcase.ToCamel(keys[i]))                    
        if !fv.IsValid() {
            return nil, fmt.Errorf("field does not exist %q", keys[i])    
        }
        if fv.CanSet() && reflect.TypeOf(val).AssignableTo(fv.Type()) {   
            fv.Set(reflect.ValueOf(val))                                  
        }                                                                 
    }
    return v, nil                                                         
}                                                                         

It uses a thirdparty library to convert the name to CamelCase, but that could be done locally, I was just being lazy.
(an added benefit with this version is that it will error out if a correct struct field can not be found).

In addition it might be beneficial to support tags as an alternative to strict field naming similar to how the json marshalling works, so it would be possible to do something along these lines.

type MyStruct struct {
    Foo int `kdb:"this_is_a_field"`
}

I'm happy to write up a PR if you think this would be beneficial.

I'm also working on functionality to Marshal structs and maps into Dicts that might be useful as well.

@sv
Copy link
Owner

sv commented Jun 28, 2019

Yes, struct field names are better and how it should be done. Never got around to implement it.

Have a look at this branch - https://github.com/sv/kdbgo/tree/v1beta . There are some api changes, but should be much cleaner overall

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants