Code Monkey home page Code Monkey logo

jsongen's Introduction

Purpose

JSONGen is a tool for generating native Golang types from JSON objects. This automates what is otherwise a very tedious and error prone task when working with JSON.

Build Status GPLv3 License

Usage

$ jsongen -h
Usage of jsongen:
  -dump="NUL": Dump tree structure to file.
  -normalize=true: Squash arrays of struct and determine primitive array type.
  -title=true: Convert identifiers to title case, treating '_' and '-' as word boundaries.

Reading from stdin can be done as follows:

$ cat test.json | jsongen

Or a filename can be passed:

$ jsongen test.json

Using test.json as input the example will produce:

type _ struct {
	Bool              bool          `json:"bool"`
	Boollist          []bool        `json:"boollist"`
	Float             float64       `json:"float"`
	Floatlist         []float64     `json:"floatlist"`
	Heterogeneouslist []interface{} `json:"heterogeneouslist"`
	Int               int64         `json:"int"`
	Intlist           []int64       `json:"intlist"`
	Nil               interface{}   `json:"nil"`
	Nillist           []interface{} `json:"nillist"`
	Sanitary          string        `json:"_Sanitary"`
	Sanitary          string
	Sanitary0         string
	String            string   `json:"string"`
	Stringlist        []string `json:"stringlist"`
	Struct            struct {
		Bool   bool        `json:"bool"`
		Float  float64     `json:"float"`
		Int    int64       `json:"int"`
		Nil    interface{} `json:"nil"`
		String string      `json:"string"`
	} `json:"struct"`
	Structlist []struct {
		Bool   bool    `json:"bool"`
		Float  float64 `json:"float"`
		Int    int64   `json:"int"`
		String string  `json:"string"`
	} `json:"structlist"`
	Structlistsquash []struct {
		Bool   bool    `json:"bool"`
		Float  float64 `json:"float"`
		Int    int64   `json:"int"`
		String string  `json:"string"`
	} `json:"structlistsquash"`
	Structlistsquashconflict []struct {
		Bool     bool        `json:"bool"`
		Conflict interface{} `json:"conflict"`
		Float    float64     `json:"float"`
		Int      int64       `json:"int"`
		String   string      `json:"string"`
	} `json:"structlistsquashconflict"`
	TitleCase  string `json:"title case"`
	TitleCase  string `json:"title_case"`
	TitleCase  string `json:"title-case"`
	Titlecase  string `json:"titlecase"`
	Unsanitary string `json:"0Unsanitary"`
	_          string `json:"123"`
}

Parsing

Field Names

  • Field names are sanitized and written as exported fields of the generated type.
  • If sanitizing produces an empty string the identifier is changed to _, this will need to be set by hand in order to properly decode the type.
  • If sanitizing produces a field name different from the original value a JSON tag is added to the field.
  • Spaces and - are converted to _.
  • Field names are converted to title case treating _ and - as word boundaries along with spaces. This can be disabled using -title=false.

Types

Primitive

  • Primitive types are parsed and stored as-is.
  • Valid types are bool, int64, float64 and string.
  • The JSON value null is translated to the empty interface.

Object

  • Object types are treated as structs.
  • Fields of structures are sorted lexicographically by sanitized field name.
  • If a structure contains duplicate fields of different types, the type will be chosen at random since Golang's map iteration order is undefined. This shouldn't be a problem since this is not permitted in JSON specification, but this is the expected behavior should it happen.

Lists

  • A homogeneous list of primitive values are treated as a list of the primitive type e.g.: []float64
  • Lists of heterogeneous types are treated as a list of the empty interface: []interface{}
  • Lists containing both integers and floating point values are interpreted as []float64.
  • Lists with object elements are treated as a list of structs.
    • Fields of each element are "squashed" into a single struct. The result is an array of a struct containing all encountered fields.
    • If a field in one element has a different type in another of the same list, the offending field is treated as an empty interface.

Examples of all of the above can be found in test.json.

Caveats

  • Currently sibling field names are not guaranteed to be unique.

License

The source of this project is licensed under GNU GPL v3.0, according to http://choosealicense.com/licenses/gpl-3.0/:

Required:

  • Disclose Source: Source code must be made available when distributing the software. In the case of LGPL, the source for the library (and not the entire program) must be made available.
  • License and copyright notice: Include a copy of the license and copyright notice with the code.
  • State Changes: Indicate significant changes made to the code.

Permitted:

  • Commercial Use: This software and derivatives may be used for commercial purposes.
  • Distribution: You may distribute this software.
  • Modification: This software may be modified.
  • Patent Grant: This license provides an express grant of patent rights from the contributor to the recipient.
  • Private Use: You may use and modify the software without distributing it.

Forbidden:

  • Hold Liable: Software is provided without warranty and the software author/license owner cannot be held liable for damages.
  • Sublicensing: You may not grant a sublicense to modify and distribute this software to third parties not included in the license.

Feedback

If you find a case that produces incorrect results or you have a feature suggestion, let me know: submit an issue.

jsongen's People

Contributors

bemasher avatar benctamas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsongen's Issues

can't convert this type

Our service provider give this kind response,i can't use jsongen to convert it,any suggestions?

{
  "action":"GetMonitorResponse",
  "meter_set":[
    {
      "data":[
        [1392072000,[12,12]],
        [12,12],
        [12,12],
        [11,11],
        [11,11],
        [11,12],
        [15,23],
        [15,29],
        [11,12]
      ],
      "vxnet_id":"vxnet-0",
      "meter_id":"52:54:f4:98:5d:f3",
      "sequence":0
    },
    {
      "data":[
        [1392072000,[0,14440]],
        [0,13762],
        [0,13901],
        [0,14546],
        [0,14710],
        [0,14730],
        [0,14655],
        [0,14898],
        [0,14772]],
      "meter_id":"disk-os"
    },
    {
      "data":[
        [1392072000,7],
        7,
        7,
        7,
        7,
        6,
        7,
        11,
        7
      ],
      "meter_id":"cpu"
    }
  ],
  "ret_code":0,
  "resource_id":"i-1234abcd"}

Keys should be camel-case

JavaScript Object Notation should adhere to JS convention, which is camel-case with leading lower-case character. In Go, leading uppercase is important to export the field. Though in JavaScript, uppercase variables denote a class, where as lower-case are used for variables and properties. Underscore separators will yield a valid identifier though they are a Ruby convention, not a JavaScript convention. Using a dash should be avoided because in JavaScript:

//This is invalid syntax:
obj.my-property;
//So the user must do:
obj["my-property"];
//Therefore, this is better:
obj.myProperty;

Unable to convert escaped JSON

Great tool, however it appears that it is unable to parse escaped JSON correctly

Valid JSON
{ "test":"Test String", "escapedJson":"{\\"test\\":\\"test\\"}" }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.