package main import ( "io" "io/ioutil" "net/http" "strconv" "strings" ) type Leaf struct { Meta Meta Content string } type Meta struct { Title string ReadOnly bool Deleted bool } func NewHTTPRequestLeaf(r *http.Request) (Leaf, error) { var leaf Leaf if b, err := ioutil.ReadAll(r.Body); err != nil { return leaf, err } else { leaf.Content = string(b) } if leaf.Meta.Title = r.Header.Get("Title"); leaf.Meta.Title == "" { leaf.Meta.Title = "Untitled" } if readOnly := r.Header.Get("Read-Only"); readOnly == "true" { leaf.Meta.ReadOnly = true } else if readOnly == "false" { leaf.Meta.ReadOnly = false } leaf.Meta.Deleted = r.Method == http.MethodDelete return leaf, nil } func NewLeaf(title string, content string) (Leaf, error) { return NewHTTPRequestLeaf(&http.Request{ Header: http.Header{ "Title": []string{title}, }, Body: io.NopCloser(strings.NewReader(content)), }) } func (leaf Leaf) WriteHTTP(w http.ResponseWriter) error { w.Header().Set("Title", leaf.Meta.Title) w.Header().Set("Read-Only", strconv.FormatBool(leaf.Meta.ReadOnly)) _, err := w.Write([]byte(leaf.Content)) return err } func (base Leaf) Merge(updated Leaf) Leaf { if updated.Meta.Title != "" { base.Meta.Title = updated.Meta.Title } if base.Meta.Title == "" { base.Meta.Title = "Untitled" } base.Meta.Deleted = updated.Meta.Deleted base.Meta.ReadOnly = updated.Meta.ReadOnly base.Content = updated.Content return base }