go-json
go-json copied to clipboard
Marshal with case preference
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.
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
I did some job for this, https://github.com/xgomod/json
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.
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.
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,
// ...
}