EVHNGDT7VJI377HHBZ4XSJCGKFCMJUELJ4APYQVDPBAK6RNIC6AAC package pijulimport ("fmt""io")type EdgeFlags byteconst (EdgeFlagsBlock EdgeFlags = 1EdgeFlagsPseudo = 4EdgeFlagsFolder = 16EdgeFlagsParent = 32EdgeFlagsDeleted = 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 uint64func changePosition(data []byte) ([]byte, ChangePosition, error) {return mapValue(uint64LE, func(v uint64) ChangePosition {return ChangePosition(v)})(data)}type Position struct {Change HashPos 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 Positiondata, _, err := tuple(assign(&p.Change, optionalHash),assign(&p.Pos, changePosition),)(data)return data, p, err}type NewEdge struct {Previous EdgeFlagsFlag EdgeFlagsFrom PositionTo VertexIntroducedBy Hash}func newEdge(data []byte) ([]byte, NewEdge, error) {var ne NewEdgedata, _, 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 HashStart ChangePositionEnd ChangePosition}func vertex(data []byte) ([]byte, Vertex, error) {var v Vertexdata, _, 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 []PositionDownContext []PositionFlag EdgeFlagsStart ChangePositionEnd ChangePositionInode Position}func (NewVertex) isAtom() {}func newVertex(data []byte) ([]byte, NewVertex, error) {var nv NewVertexdata, _, 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 []NewEdgeInode Position}func (EdgeMap) isAtom() {}func edgeMap(data []byte) ([]byte, EdgeMap, error) {var em EdgeMapdata, _, err := tuple(assign(&em.Edges, vec(newEdge)),assign(&em.Inode, position),)(data)return data, em, err}type Local struct {Path stringLine uint64}func local(data []byte) ([]byte, Local, error) {var l Localdata, _, 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 AtomAddInode AtomContents AtomPath stringEncoding string}func (FileAdd) isHunk() {}func fileAdd(data []byte) ([]byte, FileAdd, error) {var f FileAdddata, _, 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 = vreturn 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 errorfor 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 chan0030 67 65 1e 00 00 00 00 00 00 00 32 30 32 33 2d 30 ge........2023-00040 33 2d 32 37 54 31 38 3a 35 31 3a 35 38 2e 30 32 3-27T18:51:58.020050 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,.......BCEXY0080 75 4b 57 61 51 39 36 62 74 73 6b 38 55 79 42 5a uKWaQ96btsk8UyBZ0090 57 48 4c 6a 6e 31 42 72 68 79 6b 76 38 74 75 5a WHLjn1Brhykv8tuZ00a0 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....W0120 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..[....!H0200 7b 22 73 69 67 6e 61 74 75 72 65 22 3a 22 34 63 {"signature":"4c0210 4b 4c 47 31 41 32 77 64 33 70 70 36 68 42 4d 61 KLG1A2wd3pp6hBMa0220 63 65 46 43 47 6f 38 41 44 68 55 61 44 4e 7a 33 ceFCGo8ADhUaDNz30230 31 4d 4a 65 5a 78 4e 46 59 6e 42 66 38 79 50 65 1MJeZxNFYnBf8yPe0240 70 58 66 67 6f 72 39 6f 37 38 79 38 38 43 6f 6d pXfgor9o78y88Com0250 43 33 62 31 59 7a 44 63 63 75 63 44 62 50 62 65 C3b1YzDccucDbPbe0260 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, wo0290 72 6c 64 0a 00 rld..*/