Fix up some miscellaneous shit around the project regarding lua conversions
This commit is contained in:
9
.vscode/launch.json
vendored
9
.vscode/launch.json
vendored
@@ -9,8 +9,13 @@
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${fileDirname}",
|
||||
"args": []
|
||||
"program": "${workspaceFolder}",
|
||||
"args": [
|
||||
"-mode=json",
|
||||
"$..name",
|
||||
"v='pero'",
|
||||
"test.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
28
main.go
28
main.go
@@ -32,7 +32,6 @@ var logger *log.Logger
|
||||
|
||||
var (
|
||||
fileModeFlag = flag.String("mode", "regex", "Processing mode: regex, xml, json")
|
||||
verboseFlag = flag.Bool("verbose", false, "Enable verbose output")
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -48,12 +47,6 @@ func main() {
|
||||
fmt.Fprintf(os.Stderr, "\nOptions:\n")
|
||||
fmt.Fprintf(os.Stderr, " -mode string\n")
|
||||
fmt.Fprintf(os.Stderr, " Processing mode: regex, xml, json (default \"regex\")\n")
|
||||
fmt.Fprintf(os.Stderr, " -xpath string\n")
|
||||
fmt.Fprintf(os.Stderr, " XPath expression (for XML mode)\n")
|
||||
fmt.Fprintf(os.Stderr, " -jsonpath string\n")
|
||||
fmt.Fprintf(os.Stderr, " JSONPath expression (for JSON mode)\n")
|
||||
fmt.Fprintf(os.Stderr, " -verbose\n")
|
||||
fmt.Fprintf(os.Stderr, " Enable verbose output\n")
|
||||
fmt.Fprintf(os.Stderr, "\nExamples:\n")
|
||||
fmt.Fprintf(os.Stderr, " Regex mode (default):\n")
|
||||
fmt.Fprintf(os.Stderr, " %s \"<value>(\\d+)</value>\" \"*1.5\" data.xml\n", os.Args[0])
|
||||
@@ -83,15 +76,9 @@ func main() {
|
||||
var pattern, luaExpr string
|
||||
var filePatterns []string
|
||||
|
||||
if *fileModeFlag == "regex" {
|
||||
pattern = args[0]
|
||||
luaExpr = args[1]
|
||||
filePatterns = args[2:]
|
||||
} else {
|
||||
// For XML/JSON modes, pattern comes from flags
|
||||
luaExpr = args[0]
|
||||
filePatterns = args[1:]
|
||||
}
|
||||
pattern = args[0]
|
||||
luaExpr = args[1]
|
||||
filePatterns = args[2:]
|
||||
|
||||
// Prepare the Lua expression
|
||||
originalLuaExpr := luaExpr
|
||||
@@ -124,11 +111,10 @@ func main() {
|
||||
// pattern = *xpathFlag
|
||||
// logger.Printf("Starting XML modifier with XPath %q, expression %q on %d files",
|
||||
// pattern, luaExpr, len(files))
|
||||
// case "json":
|
||||
// proc = &processor.JSONProcessor{}
|
||||
// pattern = *jsonpathFlag
|
||||
// logger.Printf("Starting JSON modifier with JSONPath %q, expression %q on %d files",
|
||||
// pattern, luaExpr, len(files))
|
||||
case "json":
|
||||
proc = &processor.JSONProcessor{}
|
||||
logger.Printf("Starting JSON modifier with JSONPath %q, expression %q on %d files",
|
||||
pattern, luaExpr, len(files))
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
@@ -3,6 +3,7 @@ package processor
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"modify/processor/jsonpath"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -67,33 +68,43 @@ func (p *JSONProcessor) ProcessContent(content string, pattern string, luaExpr s
|
||||
return content, 0, 0, nil
|
||||
}
|
||||
|
||||
// Initialize Lua
|
||||
L, err := NewLuaState()
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error creating Lua state: %v", err)
|
||||
}
|
||||
defer L.Close()
|
||||
for _, node := range nodes {
|
||||
log.Printf("Processing node at path: %s with value: %v", node.Path, node.Value)
|
||||
|
||||
err = p.ToLua(L, nodes)
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error converting to Lua: %v", err)
|
||||
}
|
||||
// Initialize Lua
|
||||
L, err := NewLuaState()
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error creating Lua state: %v", err)
|
||||
}
|
||||
defer L.Close()
|
||||
log.Println("Lua state initialized successfully.")
|
||||
|
||||
// Execute Lua script
|
||||
if err := L.DoString(luaExpr); err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error executing Lua %s: %v", luaExpr, err)
|
||||
}
|
||||
err = p.ToLua(L, node.Value)
|
||||
if err != nil {
|
||||
return content, len(nodes), 0, fmt.Errorf("error converting to Lua: %v", err)
|
||||
}
|
||||
log.Printf("Converted node value to Lua: %v", node.Value)
|
||||
|
||||
// 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)
|
||||
}
|
||||
// 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.Println("Lua script executed successfully.")
|
||||
|
||||
// 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)
|
||||
// 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)
|
||||
}
|
||||
log.Printf("Retrieved modified value from Lua: %v", result)
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// Convert the modified JSON back to a string with same formatting
|
||||
@@ -154,12 +165,16 @@ func detectJsonIndentation(content string) (string, error) {
|
||||
|
||||
// updateJSONValue updates a value in the JSON structure based on its JSONPath
|
||||
func (p *JSONProcessor) updateJSONValue(jsonData interface{}, path string, newValue interface{}) error {
|
||||
err := jsonpath.Set(jsonData, path, newValue)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update JSON value at path '%s': %w", path, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToLua converts JSON values to Lua variables
|
||||
func (p *JSONProcessor) ToLua(L *lua.LState, data interface{}) error {
|
||||
table, err := ToLuaTable(L, data)
|
||||
table, err := ToLua(L, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -170,5 +185,5 @@ func (p *JSONProcessor) ToLua(L *lua.LState, data interface{}) error {
|
||||
// FromLua retrieves values from Lua
|
||||
func (p *JSONProcessor) FromLua(L *lua.LState) (interface{}, error) {
|
||||
luaValue := L.GetGlobal("v")
|
||||
return FromLuaTable(L, luaValue.(*lua.LTable))
|
||||
return FromLua(L, luaValue)
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ package processor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
lua "github.com/yuin/gopher-lua"
|
||||
@@ -52,65 +52,75 @@ func NewLuaState() (*lua.LState, error) {
|
||||
return L, nil
|
||||
}
|
||||
|
||||
// ToLuaTable converts a struct or map to a Lua table recursively
|
||||
func ToLuaTable(L *lua.LState, data interface{}) (*lua.LTable, error) {
|
||||
luaTable := L.NewTable()
|
||||
|
||||
// ToLua converts a struct or map to a Lua table recursively
|
||||
func ToLua(L *lua.LState, data interface{}) (lua.LValue, error) {
|
||||
switch v := data.(type) {
|
||||
case map[string]interface{}:
|
||||
luaTable := L.NewTable()
|
||||
for key, value := range v {
|
||||
luaValue, err := ToLuaTable(L, value)
|
||||
luaValue, err := ToLua(L, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
luaTable.RawSetString(key, luaValue)
|
||||
}
|
||||
case struct{}:
|
||||
val := reflect.ValueOf(v)
|
||||
for i := 0; i < val.NumField(); i++ {
|
||||
field := val.Type().Field(i)
|
||||
luaValue, err := ToLuaTable(L, val.Field(i).Interface())
|
||||
return luaTable, nil
|
||||
case []interface{}:
|
||||
luaTable := L.NewTable()
|
||||
for i, value := range v {
|
||||
luaValue, err := ToLua(L, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
luaTable.RawSetString(field.Name, luaValue)
|
||||
luaTable.RawSetInt(i+1, luaValue) // Lua arrays are 1-indexed
|
||||
}
|
||||
return luaTable, nil
|
||||
case string:
|
||||
luaTable.RawSetString("v", lua.LString(v))
|
||||
return lua.LString(v), nil
|
||||
case bool:
|
||||
luaTable.RawSetString("v", lua.LBool(v))
|
||||
return lua.LBool(v), nil
|
||||
case float64:
|
||||
luaTable.RawSetString("v", lua.LNumber(v))
|
||||
return lua.LNumber(v), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported data type: %T", data)
|
||||
}
|
||||
return luaTable, nil
|
||||
}
|
||||
|
||||
// FromLuaTable converts a Lua table to a struct or map recursively
|
||||
func FromLuaTable(L *lua.LState, luaTable *lua.LTable) (map[string]interface{}, error) {
|
||||
result := make(map[string]interface{})
|
||||
|
||||
luaTable.ForEach(func(key lua.LValue, value lua.LValue) {
|
||||
switch v := value.(type) {
|
||||
case *lua.LTable:
|
||||
nestedMap, err := FromLuaTable(L, v)
|
||||
// FromLua converts a Lua table to a struct or map recursively
|
||||
func FromLua(L *lua.LState, luaValue lua.LValue) (interface{}, error) {
|
||||
switch v := luaValue.(type) {
|
||||
case *lua.LTable:
|
||||
result := make(map[string]interface{})
|
||||
v.ForEach(func(key lua.LValue, value lua.LValue) {
|
||||
result[key.String()], _ = FromLua(L, value)
|
||||
})
|
||||
// This may be a bit wasteful...
|
||||
// Hopefully it won't run often enough to matter
|
||||
isArray := true
|
||||
for key := range result {
|
||||
_, err := strconv.Atoi(key)
|
||||
if err != nil {
|
||||
return
|
||||
isArray = false
|
||||
break
|
||||
}
|
||||
result[key.String()] = nestedMap
|
||||
case lua.LString:
|
||||
result[key.String()] = string(v)
|
||||
case lua.LBool:
|
||||
result[key.String()] = bool(v)
|
||||
case lua.LNumber:
|
||||
result[key.String()] = float64(v)
|
||||
default:
|
||||
result[key.String()] = nil
|
||||
}
|
||||
})
|
||||
|
||||
return result, nil
|
||||
if isArray {
|
||||
list := make([]interface{}, 0, len(result))
|
||||
for _, value := range result {
|
||||
list = append(list, value)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
return result, nil
|
||||
case lua.LString:
|
||||
return string(v), nil
|
||||
case lua.LBool:
|
||||
return bool(v), nil
|
||||
case lua.LNumber:
|
||||
return float64(v), nil
|
||||
default:
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// InitLuaHelpers initializes common Lua helper functions
|
||||
|
Reference in New Issue
Block a user