mirror of
				https://github.com/datarhei/core.git
				synced 2025-10-27 01:41:00 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			73 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package json implements
 | |
| package json
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| // Unmarshal is a wrapper for json.Unmarshal
 | |
| func Unmarshal(data []byte, v interface{}) error {
 | |
| 	return json.Unmarshal(data, v)
 | |
| }
 | |
| 
 | |
| // FormatError takes the marshalled data and the error from Unmarshal and returns a detailed
 | |
| // error message where the error was and what the error is.
 | |
| func FormatError(input []byte, err error) error {
 | |
| 	if jsonError, ok := err.(*json.SyntaxError); ok {
 | |
| 		line, character, offsetError := lineAndCharacter(input, int(jsonError.Offset))
 | |
| 		if offsetError != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 
 | |
| 		return fmt.Errorf("syntax error at line %d, character %d: %w", line, character, err)
 | |
| 	}
 | |
| 
 | |
| 	if jsonError, ok := err.(*json.UnmarshalTypeError); ok {
 | |
| 		line, character, offsetError := lineAndCharacter(input, int(jsonError.Offset))
 | |
| 		if offsetError != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 
 | |
| 		return fmt.Errorf("expect type '%s' for '%s' at line %d, character %d: %w", jsonError.Type.String(), jsonError.Field, line, character, err)
 | |
| 	}
 | |
| 
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func lineAndCharacter(input []byte, offset int) (line int, character int, err error) {
 | |
| 	lf := byte(0x0A)
 | |
| 
 | |
| 	if offset > len(input) || offset < 0 {
 | |
| 		return 0, 0, fmt.Errorf("couldn't find offset %d within the input", offset)
 | |
| 	}
 | |
| 
 | |
| 	// Humans tend to count from 1.
 | |
| 	line = 1
 | |
| 
 | |
| 	for i, b := range input {
 | |
| 		if b == lf {
 | |
| 			line++
 | |
| 			character = 0
 | |
| 		}
 | |
| 		character++
 | |
| 		if i == offset {
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return line, character, nil
 | |
| }
 | |
| 
 | |
| func ToNumber(f float64) json.Number {
 | |
| 	var s string
 | |
| 
 | |
| 	if f == float64(int64(f)) {
 | |
| 		s = fmt.Sprintf("%.0f", f) // 0 decimal if integer
 | |
| 	} else {
 | |
| 		s = fmt.Sprintf("%.3f", f) // max. 3 decimal if float
 | |
| 	}
 | |
| 
 | |
| 	return json.Number(s)
 | |
| }
 | 
