init: Initial commit
This commit is contained in:
100
mapper.go
Normal file
100
mapper.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package gojsonmapper
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Mapper struct {
|
||||
mapping map[string]string
|
||||
}
|
||||
|
||||
func ReadMapping(path string) (map[string]string, error) {
|
||||
jsonData, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var mapping map[string]string
|
||||
err = json.Unmarshal(jsonData, &mapping)
|
||||
return mapping, nil
|
||||
}
|
||||
|
||||
func NewMapper(mapping map[string]string) *Mapper {
|
||||
return &Mapper{mapping: mapping}
|
||||
}
|
||||
|
||||
func (m *Mapper) Map(input map[string]interface{}) (map[string]interface{}, error) {
|
||||
output := make(map[string]interface{})
|
||||
for key, path := range m.mapping {
|
||||
output[key] = navigatePath(input, path)
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func navigatePath(current map[string]interface{}, path string) interface{} {
|
||||
parts := strings.Split(path, ".")
|
||||
for i, part := range parts {
|
||||
isLast := i == len(parts)-1
|
||||
if strings.Contains(part, "[") && strings.HasSuffix(part, "]") {
|
||||
key := part[:strings.Index(part, "[")]
|
||||
indexStr := part[strings.Index(part, "[")+1 : len(part)-1]
|
||||
|
||||
if current[key] == nil {
|
||||
return nil
|
||||
}
|
||||
arr, ok := current[key].([]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle mapping all elements: key[]
|
||||
if indexStr == "" {
|
||||
if isLast {
|
||||
return arr
|
||||
}
|
||||
remainingPath := strings.Join(parts[i+1:], ".")
|
||||
result := make([]interface{}, len(arr))
|
||||
for j, item := range arr {
|
||||
if nestedMap, ok := item.(map[string]interface{}); ok {
|
||||
result[j] = navigatePath(nestedMap, remainingPath)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Handle specific index: key[0]
|
||||
var index int
|
||||
fmt.Sscanf(indexStr, "%d", &index)
|
||||
if index < 0 || index >= len(arr) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if isLast {
|
||||
return arr[index]
|
||||
}
|
||||
|
||||
if nestedMap, ok := arr[index].(map[string]interface{}); ok {
|
||||
remainingPath := strings.Join(parts[i+1:], ".")
|
||||
return navigatePath(nestedMap, remainingPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Regular key access
|
||||
if isLast {
|
||||
return current[part]
|
||||
}
|
||||
|
||||
if current[part] == nil {
|
||||
return nil
|
||||
}
|
||||
var ok bool
|
||||
current, ok = current[part].(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return current
|
||||
}
|
||||
Reference in New Issue
Block a user