{-# LANGUAGE FlexibleInstances #-}-- | The 'Oid' type represents a Git hash value, whether partial or full. In-- general users do not interact with this type much, as all the top-level-- functions which expect hash values typically expect strings.moduleData.Git.Oid(Oid(..),COid(..),oidToStr,ObjRef(..),Ident(..),wrapOidPtr,compareCOid,compareCOidLen,equalCOid,stringToOid)whereimportBindings.Libgit2.OidimportControl.ApplicativeimportControl.ExceptionimportControl.MonadimportqualifiedData.ByteString.Char8asBCimportData.ByteString.UnsafeimportData.Git.ErrorimportData.StringableasSimportForeign.C.StringimportForeign.ForeignPtrimportForeign.PtrimportSystem.IO.Unsafe-- | 'COid' is a type wrapper for a foreign pointer to libgit2's 'git_oid'-- structure. Users should not have to deal with this type.newtypeCOid=COid(ForeignPtrC'git_oid)oidToStr::PtrC'git_oid->IOStringoidToStr=c'git_oid_allocfmt>=>peekCStringinstanceShowCOidwhereshow(COidcoid)=unsafePerformIO$withForeignPtrcoidoidToStr-- | 'ObjRef' refers to either a Git object of a particular type (if it has-- already been loaded into memory), or it refers to the 'COid' of that-- object in the repository. This permits deferred loading of objects-- within potentially very large structures, such as trees and commits.-- However, it also means that every access to a sub-object must use-- loadObject from the type class 'Updatable'.dataObjRefa=IdRefCOid|ObjRefaderivingShowwrapOidPtr::PtrC'git_oid->IO(ObjRefa)wrapOidPtr=newForeignPtr_>=>return.IdRef.COid-- | An 'Ident' abstracts the fact that some objects won't have an identifier-- until they are written to disk -- even if sufficient information exists-- to determine that hash value. If construct as a 'Pending' value, it is-- an 'IO' action that writes the object to disk and retrieves the resulting-- hash value from Git; if 'Stored', it is a 'COid' that is known to the-- repository.dataIdenta=Pending(a->IOCOid)|StoredCOidinstanceShow(Identa)whereshow(Pending_)="Pending"show(Storedcoid)=showcoid-- | 'Oid' represents either a full or partial SHA1 hash code used to identify-- Git objects.dataOid=OidCOid|PartialOidCOidIntinstanceShowOidwhereshow(Oidx)=showxshow(PartialOidxl)=takel$showx-- | Compare two 'COid' values for equality. More typical is to use 'compare'.compareCOid::COid->COid->Ordering(COidx)`compareCOid`(COidy)=letc=unsafePerformIO$withForeignPtrx$\x'->withForeignPtry$\y'->c'git_oid_cmpx'y'inc`compare`0-- | Compare two 'COid' values for equality, but only up to a certain length.compareCOidLen::COid->COid->Int->OrderingcompareCOidLen(COidx)(COidy)l=letc=unsafePerformIO$withForeignPtrx$\x'->withForeignPtry$\y'->c'git_oid_ncmpx'y'(fromIntegrall)inc`compare`0instanceOrdCOidwherecompare=compareCOid-- | 'True' if two 'COid' values are equal.equalCOid::Orda=>a->a->Boolx`equalCOid`y=(x`compare`y)==EQinstanceEqCOidwhere(==)=equalCOidinstanceEqOidwhere(Oidx)==(Oidy)=x`equalCOid`y(PartialOidxxl)==(PartialOidyyl)=xl==yl&&compareCOidLenxyxl==EQ_==_=False-- | Convert a hash string to a 'Maybe' 'Oid' value. If the string is less-- than 40 hexadecimal digits, the result will be of type 'PartialOid'.---- >>> stringToOid "a143ecf"-- Just a143ecf-- >>> stringToOid "a143ecf" >>= (\(Just (PartialOid _ l)) -> return $ l == 7)-- True---- >>> let hash = "6cfc2ca31732fb6fa6b54bae6e586a57a0611aab"-- >>> stringToOid hash-- Just 6cfc2ca31732fb6fa6b54bae6e586a57a0611aab-- >>> stringToOid hash >>= (\(Just (Oid _)) -> return True)-- TruestringToOid::CStringablea=>a->IO(MaybeOid)stringToOidstr|len>40=throwIOObjectIdTooLong|otherwise=dooid<-mallocForeignPtrwithCStringablestr$\cstr->withForeignPtroid$\ptr->dor<-iflen==40thenc'git_oid_fromstrptrcstrelsec'git_oid_fromstrnptrcstr(fromIntegrallen)ifr<0thenreturnNothingelsereturn.Just$iflen==40thenOid(COidoid)elsePartialOid(COidoid)lenwherelen=S.lengthstr-- Oid.hs