go-json icon indicating copy to clipboard operation
go-json copied to clipboard

Marshal with case preference

Open jhwz opened this issue 3 years ago • 6 comments

Would it be possible to create an option for the encoder to be able to specify the case style the struct fields are marshalled with?

For example, if we have

type mystruct struct {
   FieldOne string
   FieldTwo string
} 

the output will be

{
  "FieldOne" : "",
  "FieldTwo" : ""
}

but if we could specify an option to convert to say camelcase (even something as simple as lowercase the first letter) to get

{
  "fieldOne" : "",
  "fieldTwo" : ""
}

it would be much nicer than manually specifying json tags! Not sure how it would look in terms of performance. Obviously a general solution is a callback/transformation function of some kind, or could just support camelCase as that would be fast.

jhwz avatar Aug 12 '21 01:08 jhwz

For example:

type User struct {
	ID       int `json:"-"`
	Name     string
	Age      int
	Email    string
	QQNumber string `json:"QQ"`
}

user := User{
	ID:       1,
	Name:     "MJ",
	Age:      51,
	Email:    "[email protected]",
	QQNumber: "20090625",
}

b, _ := json.Marshal(user)
fmt.Println(string(b))

// we need a function like `MarshalSmart`, it can auto lowercase the first letter of json fileds if the struct field has no json tag defined.
b, _ := json.MarshalSmart(user)
fmt.Println(string(b))

prefer output:


// output of json.Marshal

{
	"Name": "MJ",
	"Age": 51,
	"Email": "[email protected]",
	"QQ": "20090625"
}

// output of json.MarshalSmart

{
	"name": "MJ",
	"age": 51,
	"email": "[email protected]",
	"QQ": "20090625"
}

the same as json.UnMarshalSmart

helphi avatar Dec 16 '21 01:12 helphi

I did some job for this, https://github.com/xgomod/json

helphi avatar Dec 17 '21 05:12 helphi

I am concerned from a performance point of view that this option affects the runtime code path. (e.g. #371 ) Performance can get worse with each additional branch.

goccy avatar Nov 14 '22 05:11 goccy

Yeah that's understandable. It's a hard feature to get right for every use case and I don't have any ideas about how you might implement it.

If others don't need this then we may as well close this issue.

jhwz avatar Nov 14 '22 09:11 jhwz

This feature is very important because our general project specification is to output JSON using camelCase. It is tedious and meaningless to add tag json: "camelCaseName" for each struct field.

Similarly, as a comparison, Rust's serde library is very user-friendly:

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] // This attr directly solves the critical problem
pub struct Model {
    pub id: String,
    pub name: String,
    // ...
}

ilxqx avatar Nov 05 '23 07:11 ilxqx