Add ID field to Entry struct with auto-generation on marshal/unmarshal

This commit is contained in:
Dan Jones 2026-03-07 18:57:33 -06:00
commit 01d6dd9b0b
2 changed files with 338 additions and 66 deletions

View file

@ -20,18 +20,47 @@ import (
const DateFormat = tools.DateFormat
type Entry struct {
// ID is an optional, but recommended field.
// When marshaling/unmarshaling, if ID is empty, one is generated.
ID string
Title string
Date time.Time
Fields Metas
}
func GenerateID() string {
host, hostErr := os.Hostname()
if hostErr != nil {
host = "localhost"
}
return fmt.Sprintf(
"tag:%s,%s:my-log/%s",
host,
time.Now().Local().Format("2006"),
uuid.NewString(),
)
}
func EnsureID(id *string, fields Metas) {
if *id != "" {
return
}
metaID, hasMetaID := fields.Get("id")
var isStringID bool
*id, isStringID = metaID.(string)
if !hasMetaID || !isStringID {
*id = GenerateID()
}
}
type metaRes struct {
out []byte
err error
}
func (e Entry) getFieldMarshalChan() chan metaRes {
size := len(e.Fields)
func getFieldMarshalChan(fields Metas) chan metaRes {
size := len(fields)
ch := make(chan metaRes, size)
var wg sync.WaitGroup
@ -53,7 +82,7 @@ func (e Entry) getFieldMarshalChan() chan metaRes {
ch <- metaRes{o, er}
}
}(e.Fields[i])
}(fields[i])
}
go func() {
@ -71,16 +100,10 @@ func (e Entry) MarshalText() ([]byte, error) {
if e.Date.IsZero() {
return []byte{}, ErrorMissingDate
}
EnsureID(&e.ID, e.Fields)
fields := e.Fields.Set("id", e.ID)
if _, hasId := e.Fields.Get("id"); !hasId {
host, hostErr := os.Hostname()
if hostErr != nil {
host = "localhost"
}
e.Fields = e.Fields.Set("id", fmt.Sprintf("tag:%s,%s:my-log/%s", host, time.Now().Format("2006"), uuid.NewString()))
}
ch := e.getFieldMarshalChan()
ch := getFieldMarshalChan(fields)
buff := &bytes.Buffer{}
buff.WriteString("@begin ")
buff.WriteString(e.Date.Format(DateFormat))
@ -124,8 +147,14 @@ func (m *Entry) UnmarshalText(in []byte) error {
m.Date = d
for meta := range ch {
if meta.Key == "id" {
if id, idIsString := meta.Value.(string); idIsString {
m.ID = id
}
}
m.Fields = append(m.Fields, meta)
}
EnsureID(&m.ID, m.Fields)
return nil
}
@ -195,11 +224,13 @@ func (e Entry) MarshalJSON() ([]byte, error) {
if e.Date == (time.Time{}) {
return []byte{}, ErrorMissingDate
}
EnsureID(&e.ID, e.Fields)
fields := e.Fields.Set("id", e.ID)
out := map[string]any{}
out["title"] = e.Title
out["date"] = e.Date.Format(time.RFC3339)
maps.Copy(out, e.Fields.Map())
maps.Copy(out, fields.Map())
return json.Marshal(out)
}
@ -281,5 +312,6 @@ func (e *Entry) UnmarshalJSON(in []byte) error {
}
e.Fields = append(e.Fields, m)
}
EnsureID(&e.ID, e.Fields)
return nil
}