Add path data to the selected nodes for reconstruction via set

This commit is contained in:
2025-03-25 16:50:42 +01:00
parent 396992b3d0
commit 20bab894e3
4 changed files with 515 additions and 237 deletions

View File

@@ -3,6 +3,7 @@ package processor
import (
"encoding/json"
"fmt"
"modify/processor/jsonpath"
"os"
"path/filepath"
"strings"
@@ -56,12 +57,12 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
}
// Find nodes matching the JSONPath pattern
paths, values, err := p.findJSONPaths(jsonData, pattern)
nodes := jsonpath.Get(jsonData, pattern)
if err != nil {
return content, 0, 0, fmt.Errorf("error executing JSONPath: %v", err)
}
matchCount := len(paths)
matchCount := len(nodes)
if matchCount == 0 {
return content, 0, 0, nil
}
@@ -69,38 +70,30 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
// Initialize Lua
L, err := NewLuaState()
if err != nil {
return content, 0, 0, fmt.Errorf("error creating Lua state: %v", err)
return content, len(nodes), 0, fmt.Errorf("error creating Lua state: %v", err)
}
defer L.Close()
// Apply modifications to each node
modCount := 0
for i, value := range values {
// Convert to Lua variables
err = p.ToLua(L, value)
if err != nil {
return content, modCount, matchCount, fmt.Errorf("error converting to Lua: %v", err)
}
err = p.ToLua(L, nodes)
if err != nil {
return content, len(nodes), 0, fmt.Errorf("error converting to Lua: %v", err)
}
// Execute Lua script
if err := L.DoString(luaExpr); err != nil {
return content, modCount, matchCount, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
}
// Execute Lua script
if err := L.DoString(luaExpr); err != nil {
return content, len(nodes), 0, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
}
// Get modified value
result, err := p.FromLua(L)
if err != nil {
return content, modCount, matchCount, fmt.Errorf("error getting result from Lua: %v", err)
}
// Get modified value
result, err := p.FromLua(L)
if err != nil {
return content, len(nodes), 0, fmt.Errorf("error getting result from Lua: %v", err)
}
// Apply the modification to the JSON data
err = p.updateJSONValue(jsonData, paths[i], result)
if err != nil {
return content, modCount, matchCount, fmt.Errorf("error updating JSON: %v", err)
}
// Increment mod count if we haven't already counted object properties
modCount++
// Apply the modification to the JSON data
err = p.updateJSONValue(jsonData, pattern, result)
if err != nil {
return content, len(nodes), 0, fmt.Errorf("error updating JSON: %v", err)
}
// Convert the modified JSON back to a string with same formatting
@@ -113,11 +106,8 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
}
if err != nil {
return content, modCount, matchCount, fmt.Errorf("error serializing JSON: %v", err)
}
return string(jsonBytes), modCount, matchCount, nil
// We changed all the nodes trust me bro
return string(jsonBytes), len(nodes), len(nodes), nil
}
// detectJsonIndentation tries to determine the indentation used in the original JSON
@@ -145,29 +135,6 @@ func detectJsonIndentation(content string) (string, error) {
return "", fmt.Errorf("no indentation detected")
}
func (p *JSONProcessor) findJSONPaths(jsonData interface{}, pattern string) ([]string, []interface{}, error) {
// / $ the root object/element
// // .. recursive descent. JSONPath borrows this syntax from E4X.
// * * wildcard. All objects/elements regardless their names.
// [] [] subscript operator. XPath uses it to iterate over element collections and for predicates. In Javascript and JSON it is the native array operator.
// patternPaths := strings.Split(pattern, ".")
// current := jsonData
// for _, path := range patternPaths {
// switch path {
// case "$":
// current = jsonData
// case "@":
// current = jsonData
// case "*":
// current = jsonData
// case "..":
// }
// }
// paths, values, err := p.findJSONPaths(jsonData, pattern)
return nil, nil, nil
}
// / Selects from the root node
// // Selects nodes in the document from the current node that match the selection no matter where they are
// . Selects the current node