omissis / go-jsonschema

A tool to generate Go data types from JSON Schema definitions.
MIT License
566 stars 90 forks source link

Nested struct support? #171

Open andrewpollock opened 10 months ago

andrewpollock commented 10 months ago

I'm here after trying and failing to use https://github.com/a-h/generate (for my use case), running into a fresher variation of https://github.com/a-h/generate/issues/67 there...

My use case is similar to what's described in aforementioned issue: I'd like to generate structs from https://csrc.nist.gov/schema/nvd/api/2.0/cve_api_json_2.0.schema and that seems to involve something Moderately Complex (I am far from a JSON spec guru).

Where schema-generate -p cves /tmp/cve_api_json_2.0.schema generates:

// JSONSchemaForNVDVulnerabilityDataAPIVersion201 
type JSONSchemaForNVDVulnerabilityDataAPIVersion201 struct {
  Format string `json:"format"`
  ResultsPerPage int `json:"resultsPerPage"`
  StartIndex int `json:"startIndex"`
  Timestamp string `json:"timestamp"`
  TotalResults int `json:"totalResults"`
  Version string `json:"version"`

  // NVD feed array of CVE
  Vulnerabilities []*DefCveItem `json:"vulnerabilities"`
}

and then fails define DefCveItem at all, producing something that isn't compiler-satisfactory,

with go-jsonschema -p cves /tmp/cve_api_json_2.0.schema at least I get:

type CveApiJson20Schema struct {
        // Format corresponds to the JSON schema field "format".
        Format string `json:"format" yaml:"format" mapstructure:"format"`

        // ResultsPerPage corresponds to the JSON schema field "resultsPerPage".
        ResultsPerPage int `json:"resultsPerPage" yaml:"resultsPerPage" mapstructure:"resultsPerPage"`

        // StartIndex corresponds to the JSON schema field "startIndex".
        StartIndex int `json:"startIndex" yaml:"startIndex" mapstructure:"startIndex"`

        // Timestamp corresponds to the JSON schema field "timestamp".
        Timestamp time.Time `json:"timestamp" yaml:"timestamp" mapstructure:"timestamp"`

        // TotalResults corresponds to the JSON schema field "totalResults".
        TotalResults int `json:"totalResults" yaml:"totalResults" mapstructure:"totalResults"`

        // Version corresponds to the JSON schema field "version".
        Version string `json:"version" yaml:"version" mapstructure:"version"`

        // NVD feed array of CVE
        Vulnerabilities []DefCveItem `json:"vulnerabilities" yaml:"vulnerabilities" mapstructure:"vulnerabilities"`
}

type DefCveItem interface{}

this just leaves the definition of DefCveItem a little... non-specific for my liking/needs.

nick-jones commented 9 months ago

Definitions are handled. What seems to be tripping things up is the lack of type declaration for the defintion of def_cve_item - I'm no expert on the various spec versions, but it looks like they should be explicitly stated in draft-07

After manually patching "type": "object" in, I get the following:

type DefCveItem struct {
    // Cve corresponds to the JSON schema field "cve".
    Cve CveItem `json:"cve" yaml:"cve" mapstructure:"cve"`
}