mirror of
https://github.com/Smaug123/managed-git
synced 2025-10-10 02:08:55 +00:00
Learn to read packfiles (#5)
This commit is contained in:
88
Git/Tag.fs
Normal file
88
Git/Tag.fs
Normal file
@@ -0,0 +1,88 @@
|
||||
namespace Git
|
||||
|
||||
open System.IO
|
||||
open System.Text
|
||||
open Git.Internals
|
||||
|
||||
type TaggedObjectType =
|
||||
| Commit
|
||||
|
||||
override this.ToString () =
|
||||
match this with
|
||||
| TaggedObjectType.Commit -> "commit"
|
||||
|
||||
static member Parse (s : string) =
|
||||
match s with
|
||||
| "commit" -> TaggedObjectType.Commit
|
||||
| _ -> failwithf "Unrecognised tagged object type: %s" s
|
||||
|
||||
type TagEntry =
|
||||
{
|
||||
Object : Hash
|
||||
Type : TaggedObjectType
|
||||
Name : string
|
||||
Tagger : Contributor
|
||||
Message : string
|
||||
}
|
||||
|
||||
override this.ToString () =
|
||||
sprintf "object %O\ntype %O\ntag %s\ntagger %O\n\n%s" this.Object this.Type this.Name this.Tagger this.Message
|
||||
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Tag =
|
||||
let encode (entry : TagEntry) : byte array =
|
||||
entry.ToString () |> Encoding.UTF8.GetBytes
|
||||
|
||||
let decode (file : byte array) : TagEntry =
|
||||
use ms = new MemoryStream (file)
|
||||
|
||||
let objectHash =
|
||||
Parse.consumeWord "tag" (OneOf [ "object" ]) ms
|
||||
|> ignore
|
||||
|
||||
match Stream.consumeTo ms (byte '\n') with
|
||||
| None -> failwith "Tag object should have had a newline in"
|
||||
| Some h -> h |> Hash.ofSpelling
|
||||
|
||||
let typeReferredTo =
|
||||
Parse.consumeWord "tag" (OneOf [ "type" ]) ms
|
||||
|> ignore
|
||||
|
||||
match Stream.consumeTo ms (byte '\n') with
|
||||
| None -> failwith "Tag type should have had a newline in"
|
||||
| Some h ->
|
||||
h
|
||||
|> Encoding.ASCII.GetString
|
||||
|> TaggedObjectType.Parse
|
||||
|
||||
let tagName =
|
||||
Parse.consumeWord "tag" (OneOf [ "tag" ]) ms
|
||||
|> ignore
|
||||
|
||||
match Stream.consumeTo ms (byte '\n') with
|
||||
| None -> failwith "Tag name should have had a newline in"
|
||||
| Some t -> t |> Encoding.ASCII.GetString
|
||||
|
||||
let tagger =
|
||||
Parse.consumeWord "tag" (OneOf [ "tagger" ]) ms
|
||||
|> ignore
|
||||
|
||||
Parse.consumePerson "tagger" ms
|
||||
|
||||
let trailingNewline = Stream.consumeTo ms 10uy
|
||||
|
||||
match trailingNewline with
|
||||
| None -> failwith "Tag unexpectedly ended before message"
|
||||
| Some [||] -> ()
|
||||
| Some arr -> failwithf "Unexpectedly received data in between tagger and message: %+A" arr
|
||||
|
||||
let message = Stream.consumeToEnd ms |> Encoding.UTF8.GetString
|
||||
|
||||
{
|
||||
Object = objectHash
|
||||
Type = typeReferredTo
|
||||
Name = tagName
|
||||
Tagger = tagger
|
||||
Message = message
|
||||
}
|
Reference in New Issue
Block a user