Rework rounding and building lua script
To allow user script to specify what was modified where
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"modify/processor/jsonpath"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
)
|
||||
@@ -68,6 +67,7 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
|
||||
return content, 0, 0, nil
|
||||
}
|
||||
|
||||
modCount := 0
|
||||
for _, node := range nodes {
|
||||
log.Printf("Processing node at path: %s with value: %v", node.Path, node.Value)
|
||||
|
||||
@@ -85,10 +85,14 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
|
||||
}
|
||||
log.Printf("Converted node value to Lua: %v", node.Value)
|
||||
|
||||
originalScript := luaExpr
|
||||
fullScript := BuildLuaScript(luaExpr)
|
||||
log.Printf("Original script: %q, Full script: %q", originalScript, fullScript)
|
||||
|
||||
// Execute Lua script
|
||||
log.Printf("Executing Lua script: %s", luaExpr)
|
||||
if err := L.DoString(luaExpr); err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
|
||||
log.Printf("Executing Lua script: %q", fullScript)
|
||||
if err := L.DoString(fullScript); err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error executing Lua %q: %v", fullScript, err)
|
||||
}
|
||||
log.Println("Lua script executed successfully.")
|
||||
|
||||
@@ -99,53 +103,33 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
|
||||
}
|
||||
log.Printf("Retrieved modified value from Lua: %v", result)
|
||||
|
||||
modified := false
|
||||
modified = L.GetGlobal("modified").String() == "true"
|
||||
if !modified {
|
||||
log.Printf("No changes made to node at path: %s", node.Path)
|
||||
continue
|
||||
}
|
||||
|
||||
// Apply the modification to the JSON data
|
||||
err = p.updateJSONValue(jsonData, node.Path, result)
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error updating JSON: %v", err)
|
||||
}
|
||||
log.Printf("Updated JSON at path: %s with new value: %v", node.Path, result)
|
||||
modCount++
|
||||
}
|
||||
|
||||
// Convert the modified JSON back to a string with same formatting
|
||||
var jsonBytes []byte
|
||||
if indent, err := detectJsonIndentation(content); err == nil && indent != "" {
|
||||
// Use detected indentation for output formatting
|
||||
jsonBytes, err = json.MarshalIndent(jsonData, "", indent)
|
||||
} else {
|
||||
// Fall back to standard 2-space indent
|
||||
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
|
||||
jsonBytes, err = json.MarshalIndent(jsonData, "", " ")
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error marshalling JSON: %v", err)
|
||||
}
|
||||
|
||||
// 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
|
||||
func detectJsonIndentation(content string) (string, error) {
|
||||
lines := strings.Split(content, "\n")
|
||||
if len(lines) < 2 {
|
||||
return "", fmt.Errorf("not enough lines to detect indentation")
|
||||
}
|
||||
|
||||
// Look for the first indented line
|
||||
for i := 1; i < len(lines); i++ {
|
||||
line := lines[i]
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if trimmed == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// Calculate leading whitespace
|
||||
indent := line[:len(line)-len(trimmed)]
|
||||
if len(indent) > 0 {
|
||||
return indent, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("no indentation detected")
|
||||
}
|
||||
|
||||
// / 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
|
||||
|
@@ -129,7 +129,10 @@ func InitLuaHelpers(L *lua.LState) error {
|
||||
-- Custom Lua helpers for math operations
|
||||
function min(a, b) return math.min(a, b) end
|
||||
function max(a, b) return math.max(a, b) end
|
||||
function round(x) return math.floor(x + 0.5) end
|
||||
function round(x, n)
|
||||
if n == nil then n = 0 end
|
||||
return math.floor(x * 10^n + 0.5) / 10^n
|
||||
end
|
||||
function floor(x) return math.floor(x) end
|
||||
function ceil(x) return math.ceil(x) end
|
||||
function upper(s) return string.upper(s) end
|
||||
@@ -149,6 +152,8 @@ end
|
||||
function is_number(str)
|
||||
return tonumber(str) ~= nil
|
||||
end
|
||||
|
||||
modified = false
|
||||
`
|
||||
if err := L.DoString(helperScript); err != nil {
|
||||
return fmt.Errorf("error loading helper functions: %v", err)
|
||||
@@ -187,7 +192,21 @@ func BuildLuaScript(luaExpr string) string {
|
||||
luaExpr = "v1 = " + luaExpr
|
||||
}
|
||||
|
||||
return luaExpr
|
||||
// This allows the user to specify whether or not they modified a value
|
||||
// If they do nothing we assume they did modify (no return at all)
|
||||
// If they return before our return then they themselves specify what they did
|
||||
// If nothing is returned lua assumes nil
|
||||
// So we can say our value was modified if the return value is either nil or true
|
||||
// If the return value is false then the user wants to keep the original
|
||||
fullScript := fmt.Sprintf(`
|
||||
function run()
|
||||
%s
|
||||
end
|
||||
local res = run()
|
||||
modified = res == nil or res
|
||||
`, luaExpr)
|
||||
|
||||
return fullScript
|
||||
}
|
||||
|
||||
// Max returns the maximum of two integers
|
||||
|
Reference in New Issue
Block a user