Files
renamer/internal/insert/preview.go
2025-10-30 15:15:16 +08:00

78 lines
2.2 KiB
Go

package insert
import (
"context"
"errors"
"fmt"
"io"
"sort"
)
// Preview computes planned insert operations, renders preview output, and returns the summary.
func Preview(ctx context.Context, req *Request, out io.Writer) (*Summary, []PlannedOperation, error) {
if req == nil {
return nil, nil, errors.New("insert request cannot be nil")
}
summary, operations, err := BuildPlan(ctx, req)
if err != nil {
return nil, nil, err
}
summary.LedgerMetadata["positionToken"] = req.PositionToken
summary.LedgerMetadata["insertText"] = req.InsertText
scope := map[string]any{
"includeDirs": req.IncludeDirs,
"recursive": req.Recursive,
"includeHidden": req.IncludeHidden,
}
if len(req.ExtensionFilter) > 0 {
scope["extensionFilter"] = append([]string(nil), req.ExtensionFilter...)
}
summary.LedgerMetadata["scope"] = scope
if out != nil {
conflictReasons := make(map[string]string, len(summary.Conflicts))
for _, conflict := range summary.Conflicts {
key := conflict.OriginalPath + "->" + conflict.ProposedPath
conflictReasons[key] = conflict.Reason
}
entries := append([]PreviewEntry(nil), summary.Entries...)
sort.SliceStable(entries, func(i, j int) bool {
return entries[i].OriginalPath < entries[j].OriginalPath
})
for _, entry := range entries {
switch entry.Status {
case StatusChanged:
fmt.Fprintf(out, "%s -> %s\n", entry.OriginalPath, entry.ProposedPath)
case StatusNoChange:
fmt.Fprintf(out, "%s (no change)\n", entry.OriginalPath)
case StatusSkipped:
reason := conflictReasons[entry.OriginalPath+"->"+entry.ProposedPath]
if reason == "" {
reason = "skipped"
}
fmt.Fprintf(out, "%s -> %s (skipped: %s)\n", entry.OriginalPath, entry.ProposedPath, reason)
}
}
if summary.TotalCandidates > 0 {
fmt.Fprintf(out, "\nSummary: %d candidates, %d will change, %d already target position\n",
summary.TotalCandidates, summary.TotalChanged, summary.NoChange)
} else {
fmt.Fprintln(out, "No candidates found.")
}
if len(summary.Warnings) > 0 {
fmt.Fprintln(out)
for _, warning := range summary.Warnings {
fmt.Fprintf(out, "Warning: %s\n", warning)
}
}
}
return summary, operations, nil
}