72 lines
1.2 KiB
Go
72 lines
1.2 KiB
Go
package collaboration
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func randomID(prefix string) string {
|
|
buf := make([]byte, 12)
|
|
if _, err := rand.Read(buf); err != nil {
|
|
panic(err)
|
|
}
|
|
return prefix + ":" + hex.EncodeToString(buf)
|
|
}
|
|
|
|
func hashAnchor(text string) string {
|
|
normalized := strings.TrimSpace(text)
|
|
sum := sha256.Sum256([]byte(normalized))
|
|
return hex.EncodeToString(sum[:8])
|
|
}
|
|
|
|
func parseTime(raw string) (time.Time, error) {
|
|
if raw == "" {
|
|
return time.Time{}, nil
|
|
}
|
|
return time.Parse(time.RFC3339, raw)
|
|
}
|
|
|
|
func formatTime(t time.Time) string {
|
|
return t.UTC().Format(time.RFC3339)
|
|
}
|
|
|
|
func ptr[T any](v T) *T {
|
|
return &v
|
|
}
|
|
|
|
func nullString(s string) *string {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
return &s
|
|
}
|
|
|
|
func scanNullString(ns *string) string {
|
|
if ns == nil {
|
|
return ""
|
|
}
|
|
return *ns
|
|
}
|
|
|
|
func coalesceString(values ...string) string {
|
|
for _, v := range values {
|
|
if v != "" {
|
|
return v
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func formatDocumentID(path string) string {
|
|
clean := strings.TrimPrefix(path, "/")
|
|
clean = strings.TrimSuffix(clean, ".md")
|
|
return "doc:" + clean
|
|
}
|
|
|
|
func documentPathFromID(id string) string {
|
|
return strings.TrimPrefix(id, "doc:")
|
|
}
|