Skip to content

Instantly share code, notes, and snippets.

@piersy
Created February 9, 2018 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save piersy/b9934790a8892db1a603820c0c23e4a7 to your computer and use it in GitHub Desktop.
Save piersy/b9934790a8892db1a603820c0c23e4a7 to your computer and use it in GitHub Desktop.
Marshal JSON in Golang using lower-camel-case object key conventions
package main
import (
"encoding/json"
"fmt"
"regexp"
"time"
"unicode"
"unicode/utf8"
)
// Regexp definitions
var keyMatchRegex = regexp.MustCompile(`\"(\w+)\":`)
var wordBarrierRegex = regexp.MustCompile(`(\w)([A-Z])`)
type conventionalMarshaller struct {
Value interface{}
}
func (c conventionalMarshaller) MarshalJSON() ([]byte, error) {
marshalled, err := json.Marshal(c.Value)
converted := keyMatchRegex.ReplaceAllFunc(
marshalled,
func(match []byte) []byte {
// Empty keys are valid JSON, only lowercase if we do not have an
// empty key.
if len(match) > 2 {
// Decode first rune after the double quotes
r, width := utf8.DecodeRune(match[1:])
r = unicode.ToLower(r)
utf8.EncodeRune(match[1:width+1], r)
}
return match
},
)
return converted, err
}
type exampleModel struct {
Title string
Description string
CreatedAt time.Time
UpdatedAt time.Time
IsActive bool
}
func main() {
model := exampleModel{
Title: "Example Title",
Description: "whatever",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
IsActive: true,
}
encoded, _ := json.MarshalIndent(conventionalMarshaller{model}, "", " ")
fmt.Println(string(encoded))
}
@piersy
Copy link
Author

piersy commented Feb 9, 2018

Adapted from here - https://gist.github.com/Rican7/39a3dc10c1499384ca91 that gist shows snake case conversion, this handles lowerCamelCase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment