Skip to content

Call UnmarshalJSON for embedded types that implement json.Unmarshaler; Update Network v2 Provider Extension to be consistent with other extensions - #304

Closed
jrperritt wants to merge 8 commits into
gophercloud:masterfrom
jrperritt:networkv2-extensions-refactor
Closed

jrperritt wants to merge 8 commits into
gophercloud:masterfrom
jrperritt:networkv2-extensions-refactor

Conversation

@jrperritt

Copy link
Copy Markdown
Contributor

For #300 and part of #298

@jrperritt

jrperritt commented Mar 21, 2017 •

Copy link
Copy Markdown
Contributor Author

cc @jtopjian

I needed to make a lot of the same changes you made to get the tests to pass, so I just rolled your changes into here.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage decreased (-0.9%) to 68.693% when pulling 1c3deb6 on jrperritt:networkv2-extensions-refactor into 9a5595b on gophercloud:master.

@coveralls

Copy link
Copy Markdown

Coverage Status

Coverage decreased (-0.7%) to 68.855% when pulling 75ca263 on jrperritt:networkv2-extensions-refactor into 9a5595b on gophercloud:master.

// Specifies whether the network resource can be accessed by any tenant or not.
Shared bool `json:"shared"`

type NetworkExt struct {

@jtopjian jtopjian Mar 22, 2017 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think extension names should be renamed to something more unique. Out of curiosity, I tried to mix two extensions in like so (renaming NetworkProviderExt to NetworkExt):

type NetworkWithExt {
        networks.Network
        provider.NetworkExt
        external.NetworkExt
}

And got a Go error of:

duplicate field NetworkExt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point. Will change.

Comment thread results.go
if err != nil {
return err
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I'm able to follow along what's going on here. The only thing I'm unsure about is why a Marshal/Unmarshal is being performed here and again on each anonymous struct?

@jrperritt jrperritt Mar 22, 2017 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll add some comments and unit tests. Basically, the first json.Unmarshal will handle any response objects the don't have embedded structs. The other is specifically for embedded structs.

When a struct is embedded, the parent will inherit a method defined on the embedded struct unless that same method is defined on the parent.

@jrperritt

Copy link
Copy Markdown
Contributor Author

I'm going to think about this some more and do some more testing: what's there was kind of thrown together in haste (read: I don't like it). In my head, if each embedded struct implements json.Unmarshaler, it should just work.

@jrperritt

jrperritt commented Mar 22, 2017 •

Copy link
Copy Markdown
Contributor Author

OK, I'm convinced that it doesn't work like I thought it did. It looks like the following rules are applied for json.Unmarshal(b, object):

  1. If object implements json.Unmarshaler, object's UnmarshalJSON method is called on object,
  2. otherwise, if object embeds any number of subojects, and at most one of those subobjects implements json.Unmarshaler, the subobject's UnmarshalJSON method is called on object,
  3. otherwise, a default json.Unmarshal is run on object. For an object with multiple embedded subobjects, each implementing json.Unmarshaler, this means none of those embedded subobjects' UnmarshalJSON methods will be called.

Case 3 above is the problem we're seeing. Though I'd like for it to work like I thought it should, the current behavior seems consistent. All the above basically means the logic currently in this PR may be necessary to achieve what we're after.

@jtopjian

jtopjian commented Aug 7, 2017

Copy link
Copy Markdown
Contributor

@jrperritt Any reason to keep this one open?

@jrperritt

Copy link
Copy Markdown
Contributor Author

I don't think so. Closing in favor of #443

@jrperritt jrperritt closed this Aug 7, 2017
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.

3 participants