package frame import ( "bytes" "fmt" "sort" "strings" "gopkg.in/src-d/go-git.v4/utils/merkletrie/noder" ) // A Frame is a collection of siblings in a trie, sorted alphabetically // by name. type Frame struct { // siblings, sorted in reverse alphabetical order by name stack []noder.Noder } type byName []noder.Noder func (a byName) Len() int { return len(a) } func (a byName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a byName) Less(i, j int) bool { return strings.Compare(a[i].Name(), a[j].Name()) < 0 } // New returns a frame with the children of the provided node. func New(n noder.Noder) (*Frame, error) { children, err := n.Children() if err != nil { return nil, err } sort.Sort(sort.Reverse(byName(children))) return &Frame{ stack: children, }, nil } // String returns the quoted names of the noders in the frame sorted in // alphabeticall order by name, surrounded by square brackets and // separated by comas. // // Examples: // [] // ["a", "b"] func (f *Frame) String() string { var buf bytes.Buffer _ = buf.WriteByte('[') sep := "" for i := f.Len() - 1; i >= 0; i-- { _, _ = buf.WriteString(sep) sep = ", " _, _ = buf.WriteString(fmt.Sprintf("%q", f.stack[i].Name())) } _ = buf.WriteByte(']') return buf.String() } // First returns, but dont extract, the noder with the alphabetically // smaller name in the frame and true if the frame was not empy. // Otherwise it returns nil and false. func (f *Frame) First() (noder.Noder, bool) { if f.Len() == 0 { return nil, false } top := f.Len() - 1 return f.stack[top], true } // Drop extracts the noder with the alphabetically smaller name in the // frame or does nothing if the frame was empty. func (f *Frame) Drop() { if f.Len() == 0 { return } top := f.Len() - 1 f.stack[top] = nil f.stack = f.stack[:top] } // Len returns the number of noders in the frame. func (f *Frame) Len() int { return len(f.stack) }