1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
let src =
Logs.Src.create "git.stream" ~doc:"logs git's internal stream computation"
module Log = (val Logs.src_log src : Logs.LOG)
let hdr = function
| `Blob -> Fmt.str "blob %Ld\000"
| `Tree -> Fmt.str "tree %Ld\000"
| `Tag -> Fmt.str "tag %Ld\000"
| `Commit -> Fmt.str "commit %Ld\000"
type ('uid, 't) digest = {
empty : 't;
feed_string : string -> 't -> 't;
feed_bigstring : Bigstringaf.t -> 't -> 't;
get : 't -> 'uid;
}
let digest digest kind length serializer v =
let hdr = hdr kind (length v) in
let state = Encore.Lavoisier.emit v serializer in
let rec go ctx = function
| Encore.Lavoisier.Partial { buffer = str; off; len; continue } ->
let str = String.sub str off len in
let ctx = digest.feed_string str ctx in
go ctx (continue ~committed:len)
| Fail -> Fmt.failwith "Invalid Git object"
| Done -> digest.get ctx
in
go (digest.feed_string hdr digest.empty) state