init: Initial commit
This commit is contained in:
60
README.md
Normal file
60
README.md
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Go JSON Mapper (gojsonmapper)
|
||||||
|
|
||||||
|
This is a simple library that allows you to map different JSON objects to each other.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
This example shows how to map a JSON object to another JSON object.
|
||||||
|
|
||||||
|
### Mapping
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "data.name",
|
||||||
|
"address": "data.addresses[0]"
|
||||||
|
}
|
||||||
|
````
|
||||||
|
|
||||||
|
### Input JSON
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"name": "John Doe",
|
||||||
|
"addresses": [
|
||||||
|
"123 Main St"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output JSON
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "John Doe",
|
||||||
|
"address": "123 Main St"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Read Mapping
|
||||||
|
|
||||||
|
```go
|
||||||
|
mapping, err := ReadMapping("mapping.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Map Input
|
||||||
|
|
||||||
|
```go
|
||||||
|
mapper := NewMapper(mapping)
|
||||||
|
output, err := mapper.Map(input)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println(output)
|
||||||
|
```
|
||||||
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