aboutsummaryrefslogtreecommitdiff
path: root/obj_tree.go
diff options
context:
space:
mode:
Diffstat (limited to 'obj_tree.go')
-rw-r--r--obj_tree.go36
1 files changed, 19 insertions, 17 deletions
diff --git a/obj_tree.go b/obj_tree.go
index 55a27a08..c025dfa3 100644
--- a/obj_tree.go
+++ b/obj_tree.go
@@ -8,26 +8,27 @@ import (
)
// Tree represents a Git tree object.
-type Tree struct {
- Hash Hash
- Entries []TreeEntry
+type Tree[T HashType] struct {
+ Hash Hash[T]
+ Entries []TreeEntry[T]
}
// TreeEntry represents a single entry in a Git tree.
-type TreeEntry struct {
+type TreeEntry[T HashType] struct {
Mode uint32
Name []byte
- ID Hash
+ ID Hash[T]
}
// ObjType allows Tree to satisfy the Object interface.
-func (*Tree) ObjType() ObjType {
+func (*Tree[T]) ObjType() ObjType {
return ObjTree
}
// parseTree decodes a tree body.
-func parseTree(id Hash, body []byte, hashSize int) (*Tree, error) {
- var entries []TreeEntry
+func parseTree[T HashType](id Hash[T], body []byte) (*Tree[T], error) {
+ var entries []TreeEntry[T]
+ hashSize := hashLen[T]()
i := 0
for i < len(body) {
space := bytes.IndexByte(body[i:], ' ')
@@ -47,8 +48,8 @@ func parseTree(id Hash, body []byte, hashSize int) (*Tree, error) {
if i+hashSize > len(body) {
return nil, errors.New("furgit: tree: truncated child hash")
}
- var child Hash
- copy(child[:], body[i:i+hashSize])
+ var child Hash[T]
+ copy(child.Slice(), body[i:i+hashSize])
i += hashSize
mode, err := strconv.ParseUint(string(modeBytes), 8, 32)
@@ -56,7 +57,7 @@ func parseTree(id Hash, body []byte, hashSize int) (*Tree, error) {
return nil, fmt.Errorf("furgit: tree: parse mode: %w", err)
}
- entry := TreeEntry{
+ entry := TreeEntry[T]{
Mode: uint32(mode),
Name: append([]byte(nil), nameBytes...),
ID: child,
@@ -64,14 +65,15 @@ func parseTree(id Hash, body []byte, hashSize int) (*Tree, error) {
entries = append(entries, entry)
}
- return &Tree{
+ return &Tree[T]{
Hash: id,
Entries: entries,
}, nil
}
// treeBody builds the entry list for a tree without the Git header.
-func treeBody(t *Tree, hashSize int) []byte {
+func treeBody[T HashType](t *Tree[T]) []byte {
+ hashSize := hashLen[T]()
var bodyLen int
for _, e := range t.Entries {
mode := strconv.FormatUint(uint64(e.Mode), 8)
@@ -88,15 +90,15 @@ func treeBody(t *Tree, hashSize int) []byte {
pos += copy(body[pos:], e.Name)
body[pos] = 0
pos++
- pos += copy(body[pos:], e.ID[:hashSize])
+ pos += copy(body[pos:], e.ID.Slice()[:hashSize])
}
return body
}
// Serialize renders a Tree into canonical Git format.
-func (t *Tree) Serialize(hashSize int) ([]byte, error) {
- body := treeBody(t, hashSize)
+func (t *Tree[T]) Serialize() ([]byte, error) {
+ body := treeBody(t)
header, err := headerForType(ObjTree, body)
if err != nil {
return nil, err
@@ -109,7 +111,7 @@ func (t *Tree) Serialize(hashSize int) ([]byte, error) {
}
// Entry looks up a tree entry by name.
-func (t *Tree) Entry(name []byte) *TreeEntry {
+func (t *Tree[T]) Entry(name []byte) *TreeEntry[T] {
low, high := 0, len(t.Entries)-1
for low <= high {
mid := (low + high) / 2