package models import ( "bytes" "errors" "strings" "sync" "time" ) const DateFormat = "January 02, 2006 at 03:04:05PM -0700" type Entry struct { Title string Date time.Time Fields []Meta } type metaRes struct { out []byte err error } func (e Entry) getFieldMarshalChan() chan metaRes { size := len(e.Fields) ch := make(chan metaRes, size) var wg sync.WaitGroup // @todo figure out a way to handle json field for i := 0; i < size; i++ { wg.Add(1) go func(i int) { defer wg.Done() o, er := e.Fields[i].MarshalText() ch <- metaRes{o, er} }(i) } go func() { wg.Wait() close(ch) }() return ch } func (e Entry) MarshalText() ([]byte, error) { e.Title = strings.TrimSpace(e.Title) if e.Title == "" { return []byte{}, errors.New("Empty title") } if e.Date == (time.Time{}) { return []byte{}, errors.New("Empty date") } ch := e.getFieldMarshalChan() buff := &bytes.Buffer{} buff.WriteString("@begin ") buff.WriteString(e.Date.Format(DateFormat)) buff.WriteString(" - ") buff.WriteString(e.Title) for res := range ch { if res.err == nil && len(res.out) > 0 { buff.WriteString("\n") buff.Write(res.out) } } buff.WriteString(" @end") return buff.Bytes(), nil }