58 lines
1.4 KiB
Go
58 lines
1.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"cook/logger"
|
|
"fmt"
|
|
"sort"
|
|
)
|
|
|
|
type ReplaceCommand struct {
|
|
From int
|
|
To int
|
|
With string
|
|
}
|
|
|
|
func ExecuteModifications(modifications []ReplaceCommand, fileData string) (string, int) {
|
|
var err error
|
|
|
|
sort.Slice(modifications, func(i, j int) bool {
|
|
return modifications[i].From > modifications[j].From
|
|
})
|
|
logger.Trace("Preparing to apply %d replacement commands in reverse order", len(modifications))
|
|
|
|
executed := 0
|
|
for _, modification := range modifications {
|
|
fileData, err = modification.Execute(fileData)
|
|
if err != nil {
|
|
logger.Error("Failed to execute replacement: %v", err)
|
|
continue
|
|
}
|
|
executed++
|
|
}
|
|
logger.Info("Successfully applied %d text replacements", executed)
|
|
return fileData, executed
|
|
}
|
|
|
|
func (m *ReplaceCommand) Execute(fileDataStr string) (string, error) {
|
|
err := m.Validate(len(fileDataStr))
|
|
if err != nil {
|
|
return fileDataStr, fmt.Errorf("failed to validate modification: %v", err)
|
|
}
|
|
|
|
logger.Trace("Replace pos %d-%d with %q", m.From, m.To, m.With)
|
|
return fileDataStr[:m.From] + m.With + fileDataStr[m.To:], nil
|
|
}
|
|
|
|
func (m *ReplaceCommand) Validate(maxsize int) error {
|
|
if m.To < m.From {
|
|
return fmt.Errorf("command to is less than from: %v", m)
|
|
}
|
|
if m.From > maxsize || m.To > maxsize {
|
|
return fmt.Errorf("command from or to is greater than replacement length: %v", m)
|
|
}
|
|
if m.From < 0 || m.To < 0 {
|
|
return fmt.Errorf("command from or to is less than 0: %v", m)
|
|
}
|
|
return nil
|
|
}
|