mirror of
https://github.com/openshift/installer.git
synced 2026-02-06 09:47:02 +01:00
119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
// Package edit provides edit scripts.
|
|
// Edit scripts are a core notion for diffs.
|
|
// They represent a way to go from A to B by a sequence
|
|
// of insertions, deletions, and equal elements.
|
|
package edit
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// A Script is an edit script to alter A into B.
|
|
type Script struct {
|
|
Ranges []Range
|
|
}
|
|
|
|
// NewScript returns a Script containing the ranges r.
|
|
// It is only a convenience wrapper used to reduce line noise.
|
|
func NewScript(r ...Range) Script {
|
|
return Script{Ranges: r}
|
|
}
|
|
|
|
// IsIdentity reports whether s is the identity edit script,
|
|
// that is, whether A and B are identical.
|
|
func (s *Script) IsIdentity() bool {
|
|
for _, r := range s.Ranges {
|
|
if !r.IsEqual() {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Stat reports the total number of insertions and deletions in s.
|
|
func (s *Script) Stat() (ins, del int) {
|
|
for _, r := range s.Ranges {
|
|
switch {
|
|
case r.IsDelete():
|
|
del += r.HighA - r.LowA
|
|
case r.IsInsert():
|
|
ins += r.HighB - r.LowB
|
|
}
|
|
}
|
|
return ins, del
|
|
}
|
|
|
|
// dump formats s for debugging.
|
|
func (s *Script) dump() string {
|
|
buf := new(strings.Builder)
|
|
for _, r := range s.Ranges {
|
|
fmt.Fprintln(buf, r)
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// A Range is a pair of clopen index ranges.
|
|
// It represents the elements A[LowA:HighA] and B[LowB:HighB].
|
|
type Range struct {
|
|
LowA, HighA int
|
|
LowB, HighB int
|
|
}
|
|
|
|
// IsInsert reports whether r represents an insertion in a Script.
|
|
// If so, the inserted elements are B[LowB:HighB].
|
|
func (r *Range) IsInsert() bool {
|
|
return r.LowA == r.HighA
|
|
}
|
|
|
|
// IsDelete reports whether r represents a deletion in a Script.
|
|
// If so, the deleted elements are A[LowA:HighA].
|
|
func (r *Range) IsDelete() bool {
|
|
return r.LowB == r.HighB
|
|
}
|
|
|
|
// IsEqual reports whether r represents a series of equal elements in a Script.
|
|
// If so, the elements A[LowA:HighA] are equal to the elements B[LowB:HighB].
|
|
func (r *Range) IsEqual() bool {
|
|
return r.HighB-r.LowB == r.HighA-r.LowA
|
|
}
|
|
|
|
// An Op is a edit operation in a Script.
|
|
type Op int8
|
|
|
|
//go:generate stringer -type Op
|
|
|
|
const (
|
|
Del Op = -1 // delete
|
|
Eq Op = 0 // equal
|
|
Ins Op = 1 // insert
|
|
)
|
|
|
|
// Op reports what kind of operation r represents.
|
|
// This can also be determined by calling r.IsInsert,
|
|
// r.IsDelete, and r.IsEqual,
|
|
// but this form is sometimes more convenient to use.
|
|
func (r *Range) Op() Op {
|
|
if r.IsInsert() {
|
|
return Ins
|
|
}
|
|
if r.IsDelete() {
|
|
return Del
|
|
}
|
|
if r.IsEqual() {
|
|
return Eq
|
|
}
|
|
panic("malformed Range")
|
|
}
|
|
|
|
// Len reports the number of elements in r.
|
|
// In a deletion, it is the number of deleted elements.
|
|
// In an insertion, it is the number of inserted elements.
|
|
// For equal elements, it is the number of equal elements.
|
|
func (r *Range) Len() int {
|
|
if r.LowA == r.HighA {
|
|
return r.HighB - r.LowB
|
|
}
|
|
return r.HighA - r.LowA
|
|
}
|