Um JSON lint em Golang
Veja o vídeo desse arquivo aqui.
Um JSON lint em Golang
Esse é um pequeno utilitário de linha de comando para validar e formatar JSON que também pode ser usado como pacote, a ideia inicial era criar um parser para validar o JSON mas não foi necessário, o próprio Golang traz todas as informações que precisamos no erro inclusive o offset do erro e dai foi simples mostrar os erros de forma mais completa inclusive indicando com uma seta exatamente onde esta o erro.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"github.com/crgimenes/goconfig"
"github.com/gosidekick/jsonlint"
)
func printError(a ...interface{}) {
_, err := fmt.Fprintf(os.Stderr, "\x1b[91m%v\033[0;00m\n", a...)
if err != nil {
fmt.Println(err)
}
}
func printIndicator(a ...interface{}) {
_, err := fmt.Fprintf(os.Stderr, "\x1b[96m%v\033[0;00m\n", a...)
if err != nil {
fmt.Println(err)
}
}
func main() {
type configFlags struct {
Input string `json:"i" cfg:"i" cfgDefault:"stdin" cfgHelper:"input from"`
Output string `json:"o" cfg:"o" cfgDefault:"stdout" cfgHelper:"output to"`
}
cfg := configFlags{}
goconfig.PrefixEnv = "JSON_LINT"
err := goconfig.Parse(&cfg)
if err != nil {
printError(err)
os.Exit(-1)
}
var j []byte
if cfg.Input == "stdin" {
j, err = ioutil.ReadAll(os.Stdin)
if err != nil {
printError(err)
os.Exit(-1)
}
} else {
j, err = ioutil.ReadFile(cfg.Input)
if err != nil {
printError(err)
os.Exit(-1)
}
}
var m interface{}
err = json.Unmarshal(j, &m)
if err != nil {
out, offset := jsonlint.ParseJSONError(j, err)
printError(out)
if offset > 0 {
out = jsonlint.GetErrorJSONSource(j, offset)
printIndicator(out)
}
os.Exit(-1)
}
j, err = json.MarshalIndent(m, "", "\t")
if err != nil {
printError(err)
os.Exit(-1)
}
if cfg.Output == "stdout" {
fmt.Println(string(j))
return
}
err = ioutil.WriteFile(cfg.Output, j, 0644)
if err != nil {
printError(err)
}
}
Aqui temos o código do nosso utilitário que também serve de exemplo de como utilizar nosso pacote de tratamento de erro, basicamente basta passar o erro da função json.Unmarshal
para a função jsonlint.ParseJSONError
e o retorno vai ser uma string contendo uma descrição mais detalhada do erro e o offset de onde esse erro ocorreu, você pode passar o JSON que originou o erro e esse offset para a função jsonlint.GetErrorJSONSource
e ela vai gerar uma string contendo a parte do código com problemas junto com uma seta apontando para o primeiro caracter que o parser não conseguiu processar.
Esse utilitário assim como muitos outros esta sendo construído no nosso repositório do grupo de estudos de Go.
Nossos encontros ocorrem todas as quintas-feiras ás 22h00, para participar entre no canal de Golang no slack e procure por #brazil