aboutsummaryrefslogtreecommitdiff
path: root/object/tree/append.go
diff options
context:
space:
mode:
authorGravatar Runxi Yu2026-06-07 11:11:36 +0000
committerGravatar Runxi Yu2026-06-07 11:11:36 +0000
commit7e624857a3c57e927d27ecab4dea8ef20d90159b (patch)
tree6530b9556cc9e2f62d7bd7de19085eb04cd3fe9d /object/tree/append.go
parentobject/tree/mode: Initialize (diff)
object/tree: Add basic tree functions
Diffstat (limited to 'object/tree/append.go')
-rw-r--r--object/tree/append.go45
1 files changed, 45 insertions, 0 deletions
diff --git a/object/tree/append.go b/object/tree/append.go
new file mode 100644
index 00000000..9985e668
--- /dev/null
+++ b/object/tree/append.go
@@ -0,0 +1,45 @@
+package tree
+
+import (
+ "slices"
+
+ "lindenii.org/go/furgit/object/header"
+ "lindenii.org/go/furgit/object/tree/mode"
+ "lindenii.org/go/furgit/object/typ"
+)
+
+// AppendWithoutHeader renders the raw tree body bytes.
+//
+// It trusts the package invariant that the entries are valid and ordered,
+// so it does not revalidate them.
+func (tree *Tree) AppendWithoutHeader(dst []byte) ([]byte, error) {
+ var bodyLen int
+ for _, entry := range tree.entries {
+ bodyLen += mode.MaxModeDigits + 1 + len(entry.Name) + 1 + entry.ID.ObjectFormat().Size()
+ }
+
+ dst = slices.Grow(dst, bodyLen)
+
+ for _, entry := range tree.entries {
+ dst = entry.Mode.Append(dst)
+ dst = append(dst, ' ')
+ dst = append(dst, entry.Name...)
+ dst = append(dst, 0)
+ dst = append(dst, entry.ID.RawBytes()...)
+ }
+
+ return dst, nil
+}
+
+// AppendWithHeader renders the raw object (header + body).
+func (tree *Tree) AppendWithHeader(dst []byte) ([]byte, error) {
+ // TODO: Try to not allocate?
+ body, err := tree.AppendWithoutHeader(nil)
+ if err != nil {
+ return dst, err
+ }
+
+ dst = header.Append(dst, typ.TypeTree, uint64(len(body)))
+
+ return append(dst, body...), nil
+}