summaryrefslogtreecommitdiff
path: root/internal/types
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2024-05-19 18:27:49 +0300
committerPaul Buetow <paul@buetow.org>2024-05-19 18:27:49 +0300
commitbc495e96fb09ae05a101c2699a6380120bf26895 (patch)
treef70673cce6e5bfc2e00edad6b028745d6c536336 /internal/types
parent23e2603b824c0458bbd631b0a4b6af8c28439d5b (diff)
can update an entry
Diffstat (limited to 'internal/types')
-rw-r--r--internal/types/entry.go79
-rw-r--r--internal/types/entry_test.go53
2 files changed, 114 insertions, 18 deletions
diff --git a/internal/types/entry.go b/internal/types/entry.go
index 8d8339f..611cee1 100644
--- a/internal/types/entry.go
+++ b/internal/types/entry.go
@@ -13,12 +13,12 @@ import (
// Tells me whether the entry was shared to the sm platform named Name
type Shared struct {
- Name string `json:"id"`
+ Name string `json:"name"`
Is bool `json:"is,omitempty"`
}
func (s Shared) String() string {
- return fmt.Sprintf("Name:%s\nIs:%v\n", s.Name, s.Is)
+ return fmt.Sprintf("Name:%s;Is:%v", s.Name, s.Is)
}
func (s Shared) Equals(other Shared) bool {
@@ -33,13 +33,16 @@ func (s Shared) Equals(other Shared) bool {
}
type Entry struct {
- Body string `json:"body"`
- Shared []Shared `json:"shared,omitempty"`
- Epoch int `json:"epoch,omitempty"`
- ID string `json:"id,omitempty"`
- mu *sync.Mutex
+ // The unique ID of this entry.
+ ID string `json:"id,omitempty"`
+ Body string `json:"body"`
+ Shared []Shared `json:"shared,omitempty"`
+ Epoch int `json:"epoch,omitempty"`
+
+ // The checksum of the whole entry, can change depending on the state.
checksum string
checksumDirty bool
+ mu *sync.Mutex
}
func NewEntry(bytes []byte) (Entry, error) {
@@ -49,7 +52,7 @@ func NewEntry(bytes []byte) (Entry, error) {
}
e.initialize()
if e.ID == "" {
- e.ID = fmt.Sprintf("%x", sha256.Sum256(bytes))
+ e.ID = fmt.Sprintf("%x", sha256.Sum256([]byte(e.Body)))
}
return e, nil
}
@@ -74,10 +77,6 @@ func (e *Entry) initialize() {
e.checksumDirty = true
}
-func (e Entry) Update(other Entry) (Entry, bool) {
- panic("not yet impelemented")
-}
-
func (e Entry) Equals(other Entry) bool {
switch {
case e.Body != other.Body:
@@ -105,6 +104,50 @@ func (e Entry) Equals(other Entry) bool {
return true
}
+/**
+ * This updates the entry with the other entry. The Shared slice will also be
+ * updated. If entry is missing, it will be added. If entry is there, the shared
+ * Is status will eventually flip to true but never to false.
+ */
+func (e Entry) Update(other Entry) (Entry, error) {
+ if e.ID != other.ID {
+ return e, fmt.Errorf("can update entry only with other entry with same ID: %s %s", e, other)
+ }
+ e.checksumDirty = true
+
+ if e.Body != other.Body {
+ e.Body = other.Body
+ }
+
+ if e.Epoch != other.Epoch {
+ e.Epoch = other.Epoch
+ }
+
+ sharedMap := make(map[string]Shared)
+ for _, shared := range e.Shared {
+ sharedMap[shared.Name] = shared
+ }
+
+ for _, otherShared := range other.Shared {
+ shared, ok := sharedMap[otherShared.Name]
+ switch {
+ case !ok:
+ sharedMap[otherShared.Name] = shared
+ continue
+ case otherShared.Is:
+ shared.Is = true
+ sharedMap[otherShared.Name] = shared
+ }
+ }
+
+ e.Shared = e.Shared[:0]
+ for _, shared := range sharedMap {
+ e.Shared = append(e.Shared, shared)
+ }
+
+ return e, nil
+}
+
func (e Entry) Serialize() ([]byte, error) {
return json.Marshal(e)
}
@@ -123,14 +166,18 @@ func (e Entry) String() string {
sb.WriteString("ID:")
sb.WriteString(e.ID)
- sb.WriteString("\n")
- sb.WriteString(fmt.Sprintf("Epoch:%d\n", e.Epoch))
- for _, shared := range e.Shared {
+ sb.WriteString(";")
+ sb.WriteString(fmt.Sprintf("Epoch:%d;", e.Epoch))
+ sb.WriteString("Shared:[")
+ for i, shared := range e.Shared {
+ if i > 0 {
+ sb.WriteString(",")
+ }
sb.WriteString(shared.String())
}
+ sb.WriteString("];")
sb.WriteString("Body:")
sb.WriteString(e.Body)
- sb.WriteString("\n")
return sb.String()
}
diff --git a/internal/types/entry_test.go b/internal/types/entry_test.go
index d801f79..552d847 100644
--- a/internal/types/entry_test.go
+++ b/internal/types/entry_test.go
@@ -22,12 +22,31 @@ func TestEntryChecksum(t *testing.T) {
}
func twoDifferentEntries(t *testing.T) (entry1, entry2 Entry, err error) {
- entry1, err = NewEntry([]byte(`{"Body": "Body text here"}`))
+ entry1Str := `
+ {
+ "Body": "Body text here",
+ "Shared": [
+ { "Name": "Foo", "Is": true },
+ { "Name": "Bar", "Is": false }
+ ]
+ }
+ `
+ entry1, err = NewEntry([]byte(entry1Str))
if err != nil {
return
}
- entry2, err = NewEntry([]byte(`{"Body": "Body text here 2"}`))
+ entry2Str := `
+ {
+ "Body": "Body text here",
+ "Shared": [
+ { "Name": "Foo", "Is": true },
+ { "Name": "Bar", "Is": true },
+ { "Name": "Baz", "Is": false }
+ ]
+ }
+ `
+ entry2, err = NewEntry([]byte(entry2Str))
return
}
@@ -46,3 +65,33 @@ func TestEquals(t *testing.T) {
t.Log("both entries differ", entry1, entry2)
}
+
+func TestUpdate(t *testing.T) {
+ t.Parallel()
+
+ entry1, entry2, err := twoDifferentEntries(t)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ entry1, _ = entry1.Update(entry2)
+ if len(entry1.Shared) != 3 {
+ t.Error("expected 3 entries after update", entry1)
+ return
+ }
+
+ var isShared int
+ for _, shared := range entry1.Shared {
+ if shared.Is {
+ isShared++
+ }
+ }
+
+ if isShared != 2 {
+ t.Error("expected 2 shared entries after update but got", isShared, entry1)
+ return
+ }
+
+ t.Log("entry as expected after update", entry1)
+}