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

Author custom JSON marshaller functions to "omitempty" structs #18

Closed
mrutkows opened this issue May 16, 2023 · 3 comments
Closed

Author custom JSON marshaller functions to "omitempty" structs #18

mrutkows opened this issue May 16, 2023 · 3 comments

Comments

@mrutkows
Copy link
Contributor

See issue #13

As CycloneDX schema has many nested structs which are not, by default, removed if the are "empty" on output (--format json), we would need to implement (on a pre-struct basis) a custom marshaller (i.e., json.Marshaller) which allows us to decide which members of the struct should be omitted.

This is important for the LicenseChoice (specifically we need to remove the CDXAttachment child struct) and Vulnerability (specifically CDXAffect) structs to reduce output sizes.

Note: The CDXAttachment struct is reused elsewhere so the benefits should be seen in many places.

@mrutkows
Copy link
Contributor Author

See: https://stackoverflow.com/questions/46265751/omitting-json-for-empty-custom-type

if you really want to omit a field based and internal state, you need to implement json.Marshaller on your structure, not its children. The easiest way to do this would be as follows:

func (d Data) MarshalJSON() ([]byte, error) {
    if !d.Stderr.Valid {
        return json.Marshal(Data{d.X, d.Y, nil})
    }
    return json.Marshal(d)
}

@mrutkows
Copy link
Contributor Author

mrutkows commented May 17, 2023

more help... https://stackoverflow.com/questions/65200070/how-to-marshal-nested-struct-to-flat-json

type A struct {
    Value float64
    Unit  string
}

type B struct {
    a1 A
    a2 A
}

func (b *B) MarshalJSON() ([]byte, error) {
    intermediate := map[string]interface{}{
        "a1":   b.a1.Value,
        "a1_u": b.a1.Unit,
        "a2":   b.a2.Value,
        "a2_u": b.a2.Unit,
    }
    return json.Marshal(intermediate)
}

@mrutkows
Copy link
Contributor Author

Fixed by #22

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

1 participant