init
diff --git a/loop/todo.go b/loop/todo.go
new file mode 100644
index 0000000..e639857
--- /dev/null
+++ b/loop/todo.go
@@ -0,0 +1,61 @@
+package loop
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+
+ "github.com/invopop/jsonschema"
+)
+
+type Comment struct {
+ Author string `json:"author"`
+ Comment string `json:"comment"`
+}
+
+func (c Comment) String() string {
+ return fmt.Sprintf("%s: %s", c.Author, c.Comment)
+}
+
+type ToDo struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ Description string `json:"description"`
+ Items []*ToDo `json:"items"`
+ Done bool `json:"done"`
+ AssignedTo string `json:"assignedTo"`
+ Discussion []Comment `json:"discussion"`
+ lock sync.Locker
+}
+
+const tmpl = `%s: %s
+%s
+%s
+%s`
+
+func (t ToDo) String() string {
+ var comments []string
+ for _, c := range t.Discussion {
+ comments = append(comments, fmt.Sprintf("\t - %s", c.String()))
+ }
+ var items []string
+ for _, i := range t.Items {
+ items = append(items, fmt.Sprintf("\t%s", i.String()))
+ }
+ return fmt.Sprintf(tmpl, t.ID, t.Title, t.Description, strings.Join(comments, "\n"), strings.Join(items, "\n"))
+}
+
+func ToDoJSONSchema() string {
+ reflector := jsonschema.Reflector{
+ AllowAdditionalProperties: false,
+ RequiredFromJSONSchemaTags: true,
+ DoNotReference: false,
+ }
+ var v ToDo
+ s := reflector.Reflect(v)
+ b, err := s.MarshalJSON()
+ if err != nil {
+ panic(err)
+ }
+ return string(b)
+}