EVHNGDT7VJI377HHBZ4XSJCGKFCMJUELJ4APYQVDPBAK6RNIC6AAC
package pijul
import (
"fmt"
"io"
)
type EdgeFlags byte
const (
EdgeFlagsBlock EdgeFlags = 1
EdgeFlagsPseudo = 4
EdgeFlagsFolder = 16
EdgeFlagsParent = 32
EdgeFlagsDeleted = 128
)
func edgeFlags(data []byte) ([]byte, EdgeFlags, error) {
if len(data) < 1 {
return data, 0, io.ErrUnexpectedEOF
}
return data[1:], EdgeFlags(data[0]), nil
}
type ChangePosition uint64
func changePosition(data []byte) ([]byte, ChangePosition, error) {
return mapValue(uint64LE, func(v uint64) ChangePosition {
return ChangePosition(v)
})(data)
}
type Position struct {
Change Hash
Pos ChangePosition
}
func optionalHash(data []byte) ([]byte, Hash, error) {
data, hp, err := option(hash)(data)
if err != nil {
return data, Hash{}, err
}
if hp == nil {
return data, Hash{}, nil
}
return data, *hp, nil
}
func position(data []byte) ([]byte, Position, error) {
var p Position
data, _, err := tuple(
assign(&p.Change, optionalHash),
assign(&p.Pos, changePosition),
)(data)
return data, p, err
}
type NewEdge struct {
Previous EdgeFlags
Flag EdgeFlags
From Position
To Vertex
IntroducedBy Hash
}
func newEdge(data []byte) ([]byte, NewEdge, error) {
var ne NewEdge
data, _, err := tuple(
assign(&ne.Previous, edgeFlags),
assign(&ne.Flag, edgeFlags),
assign(&ne.From, position),
assign(&ne.To, vertex),
assign(&ne.IntroducedBy, optionalHash),
)(data)
return data, ne, err
}
type Vertex struct {
Change Hash
Start ChangePosition
End ChangePosition
}
func vertex(data []byte) ([]byte, Vertex, error) {
var v Vertex
data, _, err := tuple(
assign(&v.Change, optionalHash),
assign(&v.Start, changePosition),
assign(&v.End, changePosition),
)(data)
return data, v, err
}
type Atom interface {
isAtom()
}
func atom(data []byte) ([]byte, Atom, error) {
data, tag, err := uint32LE(data)
if err != nil {
return data, nil, err
}
switch tag {
case 0:
return newVertex(data)
case 1:
return edgeMap(data)
default:
return data, nil, fmt.Errorf("unknown tag for Atom: %d", tag)
}
}
type NewVertex struct {
UpContext []Position
DownContext []Position
Flag EdgeFlags
Start ChangePosition
End ChangePosition
Inode Position
}
func (NewVertex) isAtom() {}
func newVertex(data []byte) ([]byte, NewVertex, error) {
var nv NewVertex
data, _, err := tuple(
assign(&nv.UpContext, vec(position)),
assign(&nv.DownContext, vec(position)),
assign(&nv.Flag, edgeFlags),
assign(&nv.Start, changePosition),
assign(&nv.End, changePosition),
assign(&nv.Inode, position),
)(data)
return data, nv, err
}
type EdgeMap struct {
Edges []NewEdge
Inode Position
}
func (EdgeMap) isAtom() {}
func edgeMap(data []byte) ([]byte, EdgeMap, error) {
var em EdgeMap
data, _, err := tuple(
assign(&em.Edges, vec(newEdge)),
assign(&em.Inode, position),
)(data)
return data, em, err
}
type Local struct {
Path string
Line uint64
}
func local(data []byte) ([]byte, Local, error) {
var l Local
data, _, err := tuple(
assign(&l.Path, toString(lengthData(uint64LE))),
assign(&l.Line, uint64LE),
)(data)
return data, l, err
}
type Hunk interface {
isHunk()
}
func hunk(data []byte) ([]byte, Hunk, error) {
data, tag, err := uint32LE(data)
if err != nil {
return data, nil, err
}
switch tag {
case 3:
return fileAdd(data)
default:
return data, nil, fmt.Errorf("unknown tag for Hunk: %d", tag)
}
}
type FileAdd struct {
AddName Atom
AddInode Atom
Contents Atom
Path string
Encoding string
}
func (FileAdd) isHunk() {}
func fileAdd(data []byte) ([]byte, FileAdd, error) {
var f FileAdd
data, _, err := tuple(
assign(&f.AddName, atom),
assign(&f.AddInode, atom),
assign(&f.Contents, mapValue(option(atom), func(p *Atom) Atom {
if p == nil {
return nil
}
return *p
})),
assign(&f.Path, toString(lengthData(uint64LE))),
assign(&f.Encoding, mapValue(option(toString(lengthData(uint64LE))), func(p *string) string {
if p == nil {
return ""
}
return *p
})),
)(data)
return data, f, err
}
require github.com/klausman/hexdump v1.0.0 // indirect
}
}
// assign assigns the result of p to dest.
func assign[T any](dest *T, p parser[T]) parser[[]byte] {
return func(input []byte) ([]byte, []byte, error) {
rest, v, err := p(input)
if err != nil {
return input, nil, err
}
*dest = v
return rest, input[:len(input)-len(rest)], nil
}
}
func tuple[T any](parsers ...parser[T]) parser[[]T] {
return func(data []byte) ([]byte, []T, error) {
results := make([]T, len(parsers))
var err error
for i, p := range parsers {
data, results[i], err = p(data)
if err != nil {
return data, nil, err
}
}
return data, results, nil
Changes: []Hunk{
FileAdd{
AddName: NewVertex{
UpContext: []Position{
Position{
Change: Hash{0xe7, 0x82, 0xb1, 0xd7, 0xe4, 0x17, 0x64, 0xe4, 0xfe, 0x45, 0x2d, 0x6f, 0x24, 0x22, 0x40, 0x26, 0x16, 0x12, 0xb7, 0x0f, 0x42, 0x70, 0xd9, 0xac, 0xd8, 0x4e, 0x5a, 0x82, 0xea, 0x85, 0xab, 0x57},
Pos: 0x1,
},
},
DownContext: []Position{},
Flag: 0x11,
Start: 0x0,
End: 0x1d,
Inode: Position{
Change: Hash{},
Pos: 0x0,
},
},
AddInode: NewVertex{
UpContext: []Position{
Position{
Change: Hash{},
Pos: 0x1d,
},
},
DownContext: []Position{},
Flag: 0x11,
Start: 0x1e,
End: 0x1e,
Inode: Position{
Change: Hash{},
Pos: 0x0,
},
},
Contents: NewVertex{
UpContext: []Position{
Position{
Change: Hash{},
Pos: 0x1e,
},
},
DownContext: []Position{},
Flag: 0x1,
Start: 0x1f,
End: 0x2c,
Inode: Position{
Change: Hash{},
Pos: 0x1e,
},
},
Path: "hello",
Encoding: "UTF-8",
},
},
ContentsHash: Hash{0x9e, 0xb3, 0xf7, 0x5c, 0x66, 0x9f, 0x18, 0xec, 0x4f, 0xf7, 0x30, 0x51, 0x42, 0xfe, 0x79, 0xbd, 0x52, 0x87, 0x24, 0x1, 0x1a, 0xc5, 0x77, 0xe8, 0xf9, 0x5b, 0x14, 0xd9, 0xee, 0xf7, 0x21, 0x48},
/*
Hexdump of hashed data:
0000 06 00 00 00 00 00 00 00 09 00 00 00 00 00 00 00 ................
0010 53 61 79 20 68 65 6c 6c 6f 01 10 00 00 00 00 00 Say hello.......
0020 00 00 61 20 74 72 69 76 69 61 6c 20 63 68 61 6e ..a trivial chan
0030 67 65 1e 00 00 00 00 00 00 00 32 30 32 33 2d 30 ge........2023-0
0040 33 2d 32 37 54 31 38 3a 35 31 3a 35 38 2e 30 32 3-27T18:51:58.02
0050 36 30 39 37 36 30 31 5a 01 00 00 00 00 00 00 00 6097601Z........
0060 01 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 ................
0070 6b 65 79 2c 00 00 00 00 00 00 00 42 43 45 58 59 key,.......BCEXY
0080 75 4b 57 61 51 39 36 62 74 73 6b 38 55 79 42 5a uKWaQ96btsk8UyBZ
0090 57 48 4c 6a 6e 31 42 72 68 79 6b 76 38 74 75 5a WHLjn1Brhykv8tuZ
00a0 47 50 52 6a 7a 46 6e 01 00 00 00 00 00 00 00 01 GPRjzFn.........
00b0 00 00 00 e7 82 b1 d7 e4 17 64 e4 fe 45 2d 6f 24 .........d..E-o$
00c0 22 40 26 16 12 b7 0f 42 70 d9 ac d8 4e 5a 82 ea "@&....Bp...NZ..
00d0 85 ab 57 00 00 00 00 00 00 00 00 00 00 00 00 00 ..W.............
00e0 00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 00 ................
00f0 00 00 00 01 00 00 00 00 00 00 00 01 01 00 00 00 ................
0100 e7 82 b1 d7 e4 17 64 e4 fe 45 2d 6f 24 22 40 26 ......d..E-o$"@&
0110 16 12 b7 0f 42 70 d9 ac d8 4e 5a 82 ea 85 ab 57 ....Bp...NZ....W
0120 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0130 11 00 00 00 00 00 00 00 00 1d 00 00 00 00 00 00 ................
0140 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0150 00 00 01 00 00 00 00 00 00 00 00 1d 00 00 00 00 ................
0160 00 00 00 00 00 00 00 00 00 00 00 11 1e 00 00 00 ................
0170 00 00 00 00 1e 00 00 00 00 00 00 00 01 00 00 00 ................
0180 00 00 00 00 00 00 00 00 00 01 00 00 00 00 01 00 ................
0190 00 00 00 00 00 00 00 1e 00 00 00 00 00 00 00 00 ................
01a0 00 00 00 00 00 00 00 01 1f 00 00 00 00 00 00 00 ................
01b0 2c 00 00 00 00 00 00 00 00 1e 00 00 00 00 00 00 ,...............
01c0 00 05 00 00 00 00 00 00 00 68 65 6c 6c 6f 01 05 .........hello..
01d0 00 00 00 00 00 00 00 55 54 46 2d 38 01 00 00 00 .......UTF-8....
01e0 9e b3 f7 5c 66 9f 18 ec 4f f7 30 51 42 fe 79 bd ...\f...O.0QB.y.
01f0 52 87 24 01 1a c5 77 e8 f9 5b 14 d9 ee f7 21 48 R.$...w..[....!H
0200 7b 22 73 69 67 6e 61 74 75 72 65 22 3a 22 34 63 {"signature":"4c
0210 4b 4c 47 31 41 32 77 64 33 70 70 36 68 42 4d 61 KLG1A2wd3pp6hBMa
0220 63 65 46 43 47 6f 38 41 44 68 55 61 44 4e 7a 33 ceFCGo8ADhUaDNz3
0230 31 4d 4a 65 5a 78 4e 46 59 6e 42 66 38 79 50 65 1MJeZxNFYnBf8yPe
0240 70 58 66 67 6f 72 39 6f 37 38 79 38 38 43 6f 6d pXfgor9o78y88Com
0250 43 33 62 31 59 7a 44 63 63 75 63 44 62 50 62 65 C3b1YzDccucDbPbe
0260 7a 39 50 70 78 65 22 7d 00 00 05 00 00 00 00 00 z9Ppxe"}........
0270 00 00 68 65 6c 6c 6f 01 05 00 00 00 00 00 00 00 ..hello.........
0280 55 54 46 2d 38 00 00 68 65 6c 6c 6f 2c 20 77 6f UTF-8..hello, wo
0290 72 6c 64 0a 00 rld..
*/