diff options
| author | Paul Buetow <paul@buetow.org> | 2024-09-21 14:03:45 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-09-21 14:03:45 +0300 |
| commit | dff4d455e07d639b82a0bed814f41d0656e9b6d0 (patch) | |
| tree | 56289a6fd80a00a9724992ab9cb8b3d7215ebedf /internal/types | |
| parent | 780ade3dc066afb8a43be824373414f3d316ebd6 (diff) | |
cleanup
Diffstat (limited to 'internal/types')
| -rw-r--r-- | internal/types/entry.go | 199 | ||||
| -rw-r--r-- | internal/types/entry_test.go | 145 | ||||
| -rw-r--r-- | internal/types/platformname.go | 9 | ||||
| -rw-r--r-- | internal/types/shared.go | 29 | ||||
| -rw-r--r-- | internal/types/shared_test.go | 22 |
5 files changed, 0 insertions, 404 deletions
diff --git a/internal/types/entry.go b/internal/types/entry.go deleted file mode 100644 index bac8fd1..0000000 --- a/internal/types/entry.go +++ /dev/null @@ -1,199 +0,0 @@ -package types - -import ( - "crypto/sha256" - "encoding/json" - "fmt" - "maps" - "os" - "sort" - "strings" -) - -type EntryID = string -type Epoch = int - -type Entry struct { - // The unique ID of this entry. - ID EntryID `json:"id,omitempty"` - Body string `json:"body"` - Shared map[PlatformName]Shared `json:"shared,omitempty"` - Epoch Epoch `json:"epoch,omitempty"` - - // The checksum of the whole entry, can change depending on the state. - checksum string - checksumDirty bool -} - -func NewEntry(bytes []byte) (Entry, error) { - var e Entry - if err := json.Unmarshal(bytes, &e); err != nil { - return e, fmt.Errorf("unable to deserialise payload: %w", err) - } - - e.initialize() - if e.ID == "" { - e.ID = fmt.Sprintf("%x", sha256.Sum256([]byte(e.Body))) - } - - return e, nil -} - -func NewEntryFromCopy(other Entry) (Entry, error) { - e := other - e.initialize() - e.Shared = maps.Clone(other.Shared) - - return e, nil -} - -func NewEntryFromTextFile(filePath string) (Entry, error) { - var e Entry - - data, err := os.ReadFile(filePath) - if err != nil { - return e, err - } - - e.Body = string(data) - if e.ID == "" { - e.ID = fmt.Sprintf("%x", sha256.Sum256([]byte(e.Body))) - } - - e.initialize() - e.Checksum() - - return e, nil -} - -func (e *Entry) initialize() { - e.checksumDirty = true - - if e.Shared == nil { - e.Shared = make(map[PlatformName]Shared) - return - } -} - -func (e Entry) Equals(other Entry) bool { - switch { - case e.Body != other.Body: - return false - case e.Epoch != other.Epoch: - return false - case e.ID != other.ID: - return false - } - - return maps.Equal(e.Shared, other.Shared) -} - -func (e Entry) IsShared(platform PlatformName) bool { - shared, ok := e.Shared[platform] - if !ok { - return false - } - return shared.Is -} - -func (e Entry) SetShared(platform PlatformName) Entry { - e.Shared[platform] = newShared(true) - return e -} - -/** - * 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, bool, error) { - if e.ID != other.ID { - return e, false, fmt.Errorf("can update entry only with other entry with same ID: this(%s) other(%s)", e, other) - } - - var changed bool - - if e.Body != other.Body { - e.Body = other.Body - changed = true - } - - if e.Epoch != other.Epoch { - e.Epoch = other.Epoch - changed = true - } - - for otherPlatform, otherShared := range other.Shared { - shared, ok := e.Shared[otherPlatform] - switch { - case !ok: - e.Shared[otherPlatform] = shared - changed = true - case otherShared.Is && !shared.Is: - shared.Is = true - e.Shared[otherPlatform] = shared - changed = true - } - } - - if changed { - e.checksumDirty = true - } - - return e, changed, nil -} - -func (e Entry) JSONMarshal() ([]byte, error) { - return json.Marshal(e) -} - -func (e Entry) String() string { - return e.checksumBase() -} - -/** - * Used to calculate the checksum, better don't change the output, otherwise - * repository database will get confused with entry checksum mismatches. - */ -func (e Entry) checksumBase() string { - var sb strings.Builder - - sb.WriteString("ID:") - sb.WriteString(e.ID) - sb.WriteString(";") - sb.WriteString(fmt.Sprintf("Epoch:%d;", e.Epoch)) - sb.WriteString("Shared:{") - - platforms := make([]PlatformName, 0, len(e.Shared)) - for platform := range e.Shared { - platforms = append(platforms, platform) - } - sort.Strings(platforms) - - for i, patform := range platforms { - if i > 0 { - sb.WriteString(",") - } - shared := e.Shared[patform] - sb.WriteString(patform) - sb.WriteString(":{") - sb.WriteString(shared.String()) - sb.WriteString("}") - } - - sb.WriteString("};") - sb.WriteString("Body:") - sb.WriteString(e.Body) - - return sb.String() -} - -func (e *Entry) Checksum() string { - if !e.checksumDirty { - return e.checksum - } - - e.checksum = fmt.Sprintf("%x", sha256.Sum256([]byte(e.checksumBase()))) - e.checksumDirty = false - return e.checksum -} diff --git a/internal/types/entry_test.go b/internal/types/entry_test.go deleted file mode 100644 index 40f0955..0000000 --- a/internal/types/entry_test.go +++ /dev/null @@ -1,145 +0,0 @@ -package types - -import ( - "testing" -) - -func TestNewEntryFromJSON(t *testing.T) { - entry1, err := oneEntry() - if err != nil { - t.Error(err) - return - } - - t.Log("entry1", entry1) - if len(entry1.Shared) != 2 { - t.Error("expected to have two shared entries in entry1") - } - if !entry1.IsShared("Mastodon") { - t.Error("Mastodon should be shared") - } - if entry1.IsShared("LinkedIn") { - t.Error("LinkedIn should not be shared") - } -} - -func TestEntryChecksum(t *testing.T) { - t.Parallel() - - entry, err := NewEntry([]byte(`{"Body": "Body text here"}`)) - if err != nil { - t.Error(err) - return - } - - expected := "4dbd4f04d7917b1f1bd0807cf39a260efe51085d49b40469fca27b7f89cc73bd" - got := entry.Checksum() - - if expected != got { - t.Errorf("expected checksum '%s' but got '%s'", expected, got) - return - } - t.Log(entry.Checksum()) -} - -func TestEquals(t *testing.T) { - t.Parallel() - - entry1, entry2, err := twoDifferentEntries() - if err != nil { - t.Error(err) - return - } - - if entry1.Equals(entry2) { - t.Error("entries should not be equal", entry1, entry2) - } - - t.Log("both entries differ", entry1, entry2) -} - -func TestNewEntryFromCopy(t *testing.T) { - entry1, _, err := twoDifferentEntries() - if err != nil { - t.Error(err) - } - - entry2, err := NewEntryFromCopy(entry1) - if err != nil { - t.Error(err) - } - - if !entry1.Equals(entry2) { - t.Error("copy of entry entry1 does not equal") - t.Error("original:", entry1) - t.Error("copy: ", entry2) - } -} - -func TestUpdate(t *testing.T) { - t.Parallel() - - entry1, entry2, err := twoDifferentEntries() - if err != nil { - t.Error(err) - } - - var changed bool - if entry1, changed, err = entry1.Update(entry2); err != nil { - t.Error(err) - } - - if len(entry1.Shared) != 3 { - t.Error("expected 3 entries after update", entry1) - } - - if !changed { - t.Error("expected the entry to be changed after update") - } - - var sharedCount int - for _, shared := range entry1.Shared { - if shared.Is { - sharedCount++ - } - } - - if sharedCount != 2 { - t.Error("expected 2 shared entries after update but got", sharedCount, entry1) - } -} - -func oneEntry() (Entry, error) { - entry := ` - { - "body": "Body text here", - "shared": { - "Mastodon": { "is": true }, - "LinkedIn": { "is": false } - } - } - ` - return NewEntry([]byte(entry)) -} - -func anotherEntry() (Entry, error) { - entry := ` - { - "body": "Body text here", - "shared": { - "Mastodon": { "is": true }, - "LinkedIn": { "is": true }, - "Textfile": { "is": false } - } - } - ` - return NewEntry([]byte(entry)) -} - -func twoDifferentEntries() (entry1, entry2 Entry, err error) { - if entry1, err = oneEntry(); err != nil { - return - } - entry2, err = anotherEntry() - return -} diff --git a/internal/types/platformname.go b/internal/types/platformname.go deleted file mode 100644 index e94d422..0000000 --- a/internal/types/platformname.go +++ /dev/null @@ -1,9 +0,0 @@ -package types - -type PlatformName = string - -const ( - Mastodon PlatformName = "Mastodon" - LinkedIn PlatformName = "LinkedIn" - Textfile PlatformName = "Textfile" -) diff --git a/internal/types/shared.go b/internal/types/shared.go deleted file mode 100644 index c2d5a65..0000000 --- a/internal/types/shared.go +++ /dev/null @@ -1,29 +0,0 @@ -package types - -import ( - "fmt" - "time" -) - -type UnixEpoch int64 - -// Tells me whether the entry was Shared to the sm platform named Name -type Shared struct { - Is bool `json:"is,omitempty"` - Timestamp UnixEpoch `json:"timestamp,omitempty"` -} - -func newShared(is bool) Shared { - return Shared{ - Is: is, - Timestamp: UnixEpoch(time.Now().Unix()), - } -} - -func (s Shared) String() string { - return fmt.Sprintf("Is:%v;Timestamp:%v", s.Is, s.Timestamp) -} - -func (s Shared) Equals(other Shared) bool { - return s.Timestamp == other.Timestamp && s.Is == other.Is -} diff --git a/internal/types/shared_test.go b/internal/types/shared_test.go deleted file mode 100644 index e8dd78a..0000000 --- a/internal/types/shared_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package types - -import ( - "testing" - "time" -) - -func TestShared(t *testing.T) { - t.Parallel() - - before := time.Now().Unix() - shared := newShared(false) - - if before > shared.Timestamp { - t.Errorf("expected %d to be after or equal %d", shared.Timestamp, before) - } - - after := time.Now().Unix() - if after < shared.Timestamp { - t.Errorf("expected %d to be before or equal %d", shared.Timestamp, before) - } -} |
