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

Add support for inlining struct fields. #40

Merged
merged 3 commits into from
Aug 27, 2015

Conversation

rjeczalik
Copy link
Contributor

msgpack encoder differ in behaviour from the json one - the latter inlines
fields of an embedded struct as they were part of the parent struct.

While we can't change the behaviour due to compatibility reasons we can
introduce inline opt, which will make the encoding similar in
behaviour to the json one.

/cc @vmihailenco Please take a look.

@rjeczalik rjeczalik force-pushed the master branch 3 times, most recently from fbf0494 to dca6e0d Compare August 20, 2015 18:18
@vmihailenco
Copy link
Owner

Looks solid, thanks. I had something similar before, but it caused #20 and was reverted rjeczalik@f2a814a. I still have to think about implications.

if ftyp.Kind() == reflect.Ptr {
ftyp = ftyp.Elem()
}
if opts.Contains("inline") && ftyp.Kind() == reflect.Struct {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably inline -> embed to match Go naming of the concept?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed embed would fit better, however there was already precedence and inline shows up in couple of places:

So I think it'd be better to stick with inline.

@vmihailenco
Copy link
Owner

Can you please add following test case:

type CustomTime struct {
    time.Time `msgpack:,inline`
}

What is the expected behaviour in such case?

@rjeczalik rjeczalik force-pushed the master branch 2 times, most recently from c7a3141 to 520d3f3 Compare August 23, 2015 15:29
msgpack encoder differ in behaviour from the json one - the latter inlines
fields of an embedded struct as they were part of the parent struct.

While we can't change the behaviour due to compatibility reasons we can
introduce `inline` opt, which will make the encoding similar in
behaviour to the json one.
@rjeczalik
Copy link
Contributor Author

@vmihailenco Rebased with master and added a test-case for CustomTime. Please take a look.

What is the expected behaviour in such case?

I think the simplest rule here would be: if a struct has no fields to inline it'll be encoded/decode as a whole.

In particular marshalling:

type CustomTime struct {
    time.Time
}

and

type CustomTime struct {
    time.Time `msgpack:",inline"`
}

will give the same results. The same behaviour is in gopkg.in/yaml.v2, which has the inline opt.

// a whole later.
if len(flds.Fields) != 0 {
continue
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this block a bit confusing to understand. Probably:

inlinedFields := getFields(ftyp)
if len(inlinedFields) > 0 {
    inlineFields(fs, inlinedFields)
    continue
}

What do you think?

@vmihailenco
Copy link
Owner

What about inlining struct that implements CustomEncoder? Looks like in this case EncodeMsgpack(*Encoder) error method will not be called... I will try to read golang/go#6213 tomorrow to get an idea about existing design in other packages.

@rjeczalik
Copy link
Contributor Author

What about inlining struct that implements CustomEncoder?

Yup, sorry, I did not take custom serialisation into account in my initial implementation - I reworked this in my latest commit, which makes inline opt being ignored when a struct implements either CustomEncoder, CustomDecoder or both.

The other option instead of ignoring would be to firstly encode the field with custom encoder or globally registered one and then inline all fields of such struct. The implementation would be a bit more complex, so I think we could defer it to a point where such use-case would be needed and right now live with simpler implementation.

@vmihailenco What do you think?

@vmihailenco
Copy link
Owner

Actually I think inline tag should has higher priority than CustomEncoder (it seem to be more specific to me). What do you think? I will make appropriate change myself, just want to make sure will not break your code.

@rjeczalik
Copy link
Contributor Author

@vmihailenco Sure, it's fine by me.

@vmihailenco
Copy link
Owner

Thanks. I will change it in separate PR.

vmihailenco added a commit that referenced this pull request Aug 27, 2015
Add support for inlining struct fields.
@vmihailenco vmihailenco merged commit ac08bf6 into vmihailenco:master Aug 27, 2015
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

Successfully merging this pull request may close these issues.

2 participants