36 lines
948 B
Go
36 lines
948 B
Go
package source
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// DigestDocument returns a deterministic digest of the canonical source
|
|
// document content. The existing Digest field is excluded from its own digest.
|
|
func DigestDocument(doc *SourceDocument) (string, error) {
|
|
if doc == nil {
|
|
return "", fmt.Errorf("source document must not be nil")
|
|
}
|
|
payload := struct {
|
|
ID string `json:"id"`
|
|
Kind string `json:"kind"`
|
|
Format string `json:"format"`
|
|
Units []SourceUnit `json:"units"`
|
|
Metadata map[string]any `json:"metadata,omitempty"`
|
|
}{
|
|
ID: doc.ID,
|
|
Kind: doc.Kind,
|
|
Format: doc.Format,
|
|
Units: doc.Units,
|
|
Metadata: doc.Metadata,
|
|
}
|
|
encoded, err := json.Marshal(payload)
|
|
if err != nil {
|
|
return "", fmt.Errorf("encode source document for digest: %w", err)
|
|
}
|
|
sum := sha256.Sum256(encoded)
|
|
return "sha256:" + hex.EncodeToString(sum[:]), nil
|
|
}
|