Hallucinate actual json fucking thing
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
logger "git.site.quack-lab.dev/dave/cylogger"
|
logger "git.site.quack-lab.dev/dave/cylogger"
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"github.com/tidwall/sjson"
|
"github.com/tidwall/sjson"
|
||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
)
|
)
|
||||||
@@ -119,8 +118,8 @@ func applySurgicalJSONChanges(content string, originalData, modifiedData interfa
|
|||||||
return commands, nil
|
return commands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try surgical approach first
|
// Try true surgical approach that preserves formatting
|
||||||
surgicalCommands, err := applySurgicalChanges(content, originalData, modifiedData)
|
surgicalCommands, err := applyTrueSurgicalChanges(content, originalData, modifiedData)
|
||||||
if err == nil && len(surgicalCommands) > 0 {
|
if err == nil && len(surgicalCommands) > 0 {
|
||||||
return surgicalCommands, nil
|
return surgicalCommands, nil
|
||||||
}
|
}
|
||||||
@@ -140,21 +139,18 @@ func applySurgicalJSONChanges(content string, originalData, modifiedData interfa
|
|||||||
return commands, nil
|
return commands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// applySurgicalChanges attempts to make surgical changes using gjson and sjson
|
// applyTrueSurgicalChanges attempts to make surgical changes while preserving exact formatting
|
||||||
func applySurgicalChanges(content string, originalData, modifiedData interface{}) ([]utils.ReplaceCommand, error) {
|
func applyTrueSurgicalChanges(content string, originalData, modifiedData interface{}) ([]utils.ReplaceCommand, error) {
|
||||||
var commands []utils.ReplaceCommand
|
var commands []utils.ReplaceCommand
|
||||||
|
|
||||||
// Parse the original content with gjson to get the structure
|
|
||||||
result := gjson.Parse(content)
|
|
||||||
|
|
||||||
// Find changes by comparing the data structures
|
// Find changes by comparing the data structures
|
||||||
changes := findSurgicalChanges(result, originalData, modifiedData)
|
changes := findDeepChanges("", originalData, modifiedData)
|
||||||
|
|
||||||
if len(changes) == 0 {
|
if len(changes) == 0 {
|
||||||
return commands, nil
|
return commands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply changes surgically
|
// Apply changes surgically using sjson.Set() to preserve formatting
|
||||||
modifiedContent := content
|
modifiedContent := content
|
||||||
for path, newValue := range changes {
|
for path, newValue := range changes {
|
||||||
var err error
|
var err error
|
||||||
@@ -165,59 +161,94 @@ func applySurgicalChanges(content string, originalData, modifiedData interface{}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we successfully made changes, create a replacement command
|
// If we successfully made changes, create a replacement command
|
||||||
// But ensure we preserve formatting by using json.MarshalIndent
|
|
||||||
if modifiedContent != content {
|
if modifiedContent != content {
|
||||||
// Parse the surgically modified content and re-format it
|
|
||||||
var parsedData interface{}
|
|
||||||
if err := json.Unmarshal([]byte(modifiedContent), &parsedData); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to parse surgically modified content: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
formattedContent, err := json.MarshalIndent(parsedData, "", " ")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to format surgically modified content: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
commands = append(commands, utils.ReplaceCommand{
|
commands = append(commands, utils.ReplaceCommand{
|
||||||
From: 0,
|
From: 0,
|
||||||
To: len(content),
|
To: len(content),
|
||||||
With: string(formattedContent),
|
With: modifiedContent,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands, nil
|
return commands, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// findSurgicalChanges finds specific paths that need to be changed
|
// findDeepChanges recursively finds all paths that need to be changed
|
||||||
func findSurgicalChanges(result gjson.Result, original, modified interface{}) map[string]interface{} {
|
func findDeepChanges(basePath string, original, modified interface{}) map[string]interface{} {
|
||||||
changes := make(map[string]interface{})
|
changes := make(map[string]interface{})
|
||||||
|
|
||||||
switch orig := original.(type) {
|
switch orig := original.(type) {
|
||||||
case map[string]interface{}:
|
case map[string]interface{}:
|
||||||
if mod, ok := modified.(map[string]interface{}); ok {
|
if mod, ok := modified.(map[string]interface{}); ok {
|
||||||
|
// Check each key in the modified data
|
||||||
for key, modValue := range mod {
|
for key, modValue := range mod {
|
||||||
|
var currentPath string
|
||||||
|
if basePath == "" {
|
||||||
|
currentPath = key
|
||||||
|
} else {
|
||||||
|
currentPath = basePath + "." + key
|
||||||
|
}
|
||||||
|
|
||||||
if origValue, exists := orig[key]; exists {
|
if origValue, exists := orig[key]; exists {
|
||||||
// Key exists in both, check if value changed
|
// Key exists in both, check if value changed
|
||||||
if !deepEqual(origValue, modValue) {
|
if !deepEqual(origValue, modValue) {
|
||||||
changes[key] = modValue
|
// If it's a nested object/array, recurse
|
||||||
|
switch modValue.(type) {
|
||||||
|
case map[string]interface{}, []interface{}:
|
||||||
|
nestedChanges := findDeepChanges(currentPath, origValue, modValue)
|
||||||
|
for nestedPath, nestedValue := range nestedChanges {
|
||||||
|
changes[nestedPath] = nestedValue
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Primitive value changed
|
||||||
|
changes[currentPath] = modValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// New key added
|
// New key added
|
||||||
changes[key] = modValue
|
changes[currentPath] = modValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
if mod, ok := modified.([]interface{}); ok {
|
if mod, ok := modified.([]interface{}); ok {
|
||||||
// For arrays, we'll do a simple replacement for now
|
// For arrays, check each index
|
||||||
if !deepEqual(orig, mod) {
|
for i, modValue := range mod {
|
||||||
changes[""] = mod // Root path for array replacement
|
var currentPath string
|
||||||
|
if basePath == "" {
|
||||||
|
currentPath = fmt.Sprintf("%d", i)
|
||||||
|
} else {
|
||||||
|
currentPath = fmt.Sprintf("%s.%d", basePath, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
if i < len(orig) {
|
||||||
|
// Index exists in both, check if value changed
|
||||||
|
if !deepEqual(orig[i], modValue) {
|
||||||
|
// If it's a nested object/array, recurse
|
||||||
|
switch modValue.(type) {
|
||||||
|
case map[string]interface{}, []interface{}:
|
||||||
|
nestedChanges := findDeepChanges(currentPath, orig[i], modValue)
|
||||||
|
for nestedPath, nestedValue := range nestedChanges {
|
||||||
|
changes[nestedPath] = nestedValue
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// Primitive value changed
|
||||||
|
changes[currentPath] = modValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// New array element added
|
||||||
|
changes[currentPath] = modValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// For primitive types, compare directly
|
// For primitive types, compare directly
|
||||||
if !deepEqual(original, modified) {
|
if !deepEqual(original, modified) {
|
||||||
changes[""] = modified
|
if basePath == "" {
|
||||||
|
changes[""] = modified
|
||||||
|
} else {
|
||||||
|
changes[basePath] = modified
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
test_surgical.yml
Normal file
11
test_surgical.yml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
- name: SurgicalWeightTest
|
||||||
|
json: true
|
||||||
|
lua: |
|
||||||
|
-- This demonstrates surgical JSON editing
|
||||||
|
-- Only the Weight field of Item_Fiber will be modified
|
||||||
|
data.Rows[1].Weight = 999
|
||||||
|
modified = true
|
||||||
|
files:
|
||||||
|
- 'D_Itemable.json'
|
||||||
|
reset: false
|
||||||
|
loglevel: INFO
|
Reference in New Issue
Block a user