get without content

master
Bel LaPointe 2022-02-09 11:34:18 -07:00
parent eedb6cc6a5
commit 4a9ecd820a
2 changed files with 111 additions and 5 deletions

View File

@ -17,6 +17,18 @@ func (branch Branch) IsZero() bool {
return branch.Leaf == (Leaf{}) && len(branch.Branches) == 0 return branch.Leaf == (Leaf{}) && len(branch.Branches) == 0
} }
func (branch Branch) Find(baseId string) ([]string, bool) {
if _, ok := branch.Branches[baseId]; ok {
return []string{baseId}, true
}
for pid, child := range branch.Branches {
if subids, ok := child.Find(baseId); ok {
return append([]string{pid}, subids...), true
}
}
return nil, false
}
type Leaf struct { type Leaf struct {
Title string Title string
Deleted bool Deleted bool
@ -46,18 +58,30 @@ func (tree Tree) WithRoot(root string) Tree {
return tree return tree
} }
func (tree Tree) Find(baseId string) ([]string, bool) {
root, err := tree.GetRoot()
if err != nil {
return nil, false
}
return root.Find(baseId)
}
func (tree Tree) GetRootMeta() (Branch, error) {
return tree.getRoot(false)
}
func (tree Tree) GetRoot() (Branch, error) { func (tree Tree) GetRoot() (Branch, error) {
if !tree.cachedRoot.IsZero() { if !tree.cachedRoot.IsZero() {
return tree.cachedRoot, nil return tree.cachedRoot, nil
} }
got, err := tree.getRoot() got, err := tree.getRoot(true)
if err == nil { if err == nil {
tree.cachedRoot = got tree.cachedRoot = got
} }
return got, err return got, err
} }
func (tree Tree) getRoot() (Branch, error) { func (tree Tree) getRoot(withContent bool) (Branch, error) {
m := Branch{Branches: map[string]Branch{}} m := Branch{Branches: map[string]Branch{}}
entries, err := os.ReadDir(tree.root) entries, err := os.ReadDir(tree.root)
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -73,8 +97,11 @@ func (tree Tree) getRoot() (Branch, error) {
} else if err := yaml.Unmarshal(b, &m.Leaf); err != nil { } else if err := yaml.Unmarshal(b, &m.Leaf); err != nil {
return Branch{}, err return Branch{}, err
} }
if !withContent {
m.Leaf.Content = ""
}
} else if entry.IsDir() { } else if entry.IsDir() {
if branch, err := tree.WithRoot(path.Join(tree.root, entry.Name())).getRoot(); err != nil { if branch, err := tree.WithRoot(path.Join(tree.root, entry.Name())).getRoot(withContent); err != nil {
return Branch{}, err return Branch{}, err
} else { } else {
m.Branches[entry.Name()] = branch m.Branches[entry.Name()] = branch
@ -110,11 +137,16 @@ func (tree Tree) Put(id []string, input Leaf) error {
if err != nil { if err != nil {
return err return err
} }
return ensureAndWrite(tree.toData(id), b) if err := ensureAndWrite(tree.toData(id), b); err != nil {
return err
}
tree.cachedRoot = Branch{}
return nil
} }
func (tree Tree) Del(id []string) error { func (tree Tree) Del(id []string) error {
os.RemoveAll(tree.toDir(id)) os.RemoveAll(tree.toDir(id))
tree.cachedRoot = Branch{}
return nil return nil
} }

View File

@ -1,6 +1,11 @@
package main package main
import "testing" import (
"encoding/json"
"fmt"
"path"
"testing"
)
func TestTreeCrud(t *testing.T) { func TestTreeCrud(t *testing.T) {
tree := NewTree(t.TempDir()) tree := NewTree(t.TempDir())
@ -27,4 +32,73 @@ func TestTreeCrud(t *testing.T) {
} else if l != want { } else if l != want {
t.Fatal(want, l) t.Fatal(want, l)
} }
if withContent, err := tree.GetRoot(); err != nil {
t.Fatal(err)
} else if withoutContent, err := tree.GetRootMeta(); err != nil {
t.Fatal(err)
} else if fmt.Sprint(withContent) == fmt.Sprint(withoutContent) {
with, _ := json.MarshalIndent(withContent, "", " ")
without, _ := json.MarshalIndent(withoutContent, "", " ")
t.Fatalf("without content == with content: \n\twith=%s\n\twout=%s", with, without)
}
}
func TestBranchFind(t *testing.T) {
cases := map[string]struct {
input string
want []string
found bool
branch Branch
}{
"empty": {
input: "id",
want: nil,
found: false,
branch: Branch{},
},
"yes top level": {
input: "id",
want: []string{"id"},
found: true,
branch: Branch{
Branches: map[string]Branch{"id": Branch{}},
},
},
"yes deep level": {
input: "subsubid",
want: []string{"id", "subid", "subsubid"},
found: true,
branch: Branch{
Branches: map[string]Branch{"id": Branch{
Branches: map[string]Branch{"subid": Branch{
Branches: map[string]Branch{"subsubid": Branch{}}}},
}},
},
},
"no but has deep levels": {
input: "notsubsubid",
want: nil,
found: false,
branch: Branch{
Branches: map[string]Branch{"id": Branch{
Branches: map[string]Branch{"subid": Branch{
Branches: map[string]Branch{"subsubid": Branch{}}}},
}},
},
},
}
for name, d := range cases {
c := d
t.Run(name, func(t *testing.T) {
got, found := c.branch.Find(c.input)
if found != c.found {
t.Error(c.found, found)
}
if path.Join(got...) != path.Join(c.want...) {
t.Error(c.want, got)
}
})
}
} }