Skip to content

Commit

Permalink
feat: add support for dynamic partitioning config
Browse files Browse the repository at this point in the history
  • Loading branch information
akupila committed Aug 23, 2024
1 parent c174ab7 commit 18bfc8f
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 0 deletions.
46 changes: 46 additions & 0 deletions channel_config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package stream_chat

import (
"strconv"
"time"
)

// ChannelConfig is the configuration for a channel.
type ChannelConfig struct {
Name string `json:"name"`
Expand Down Expand Up @@ -34,6 +39,47 @@ type ChannelConfig struct {
BlockList string `json:"blocklist"`
BlockListBehavior modBehaviour `json:"blocklist_behavior"`
AutomodThresholds *Thresholds `json:"automod_thresholds"`

// Dynamic Partitioning
PartitionSize int `json:"partition_size,omitempty"`
PartitionTTL *DurationString `json:"partition_ttl,omitempty"`
}

// DurationString is a duration that's encoded to as a string in JSON.
type DurationString time.Duration

// NewDurationString creates a pointer to a DurationString.
func NewDurationString(d time.Duration) *DurationString {
duration := DurationString(d)
return &duration
}

// MarshalJSON encodes the duration as a string such as "2h30m".
func (d DurationString) MarshalJSON() ([]byte, error) {
if d == 0 {
return []byte("null"), nil
}
return []byte(`"` + time.Duration(d).String() + `"`), nil
}

// String returns the duration as a string such as "2h30m".
func (d DurationString) String() string {
return time.Duration(d).String()
}

// UnmarshalJSON decodes a duration from a string formatted as
// [time.Duration.String()](https://golang.org/pkg/time/#Duration.String)
func (d *DurationString) UnmarshalJSON(b []byte) error {
s, err := strconv.Unquote(string(b))
if err != nil {
return err
}
dur, err := time.ParseDuration(s)
if err != nil {
return err
}
*d = DurationString(dur)
return nil
}

type LabelThresholds struct {
Expand Down
86 changes: 86 additions & 0 deletions channel_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package stream_chat

import (
"encoding/json"
"testing"
"time"
)

func TestDuration_MarshalJSON(t *testing.T) {
tests := []struct {
name string
input DurationString
want string
}{
{
name: "Zero",
input: DurationString(0),
want: `null`,
},
{
name: "Hours",
input: DurationString(24 * time.Hour),
want: `"24h0m0s"`,
},
{
name: "Mixed",
input: DurationString(24*time.Hour + 30*time.Minute + 15*time.Second),
want: `"24h30m15s"`,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := tt.input.MarshalJSON()
if err != nil {
t.Fatal(err)
}
if string(got) != tt.want {
t.Errorf("Duration.MarshalJSON() = %q, want %q", string(got), tt.want)
}
})
}
}

func TestDuration_UnmarshalJSON(t *testing.T) {
tests := []struct {
name string
input string
want DurationString
wantErr bool
}{
{
name: "Hours",
input: `"4h"`,
want: DurationString(4 * time.Hour),
},
{
name: "Mixed",
input: `"2h30m"`,
want: DurationString(2*time.Hour + 30*time.Minute),
},
{
name: "Full",
input: `"6h0m0s"`,
want: DurationString(6 * time.Hour),
},
{
name: "Invalid",
input: "daily",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var got DurationString
err := json.Unmarshal([]byte(tt.input), &got)
if (err != nil) != tt.wantErr {
t.Fatalf("Error = %q, want error: %t", err, tt.wantErr)
}
if got.String() != tt.want.String() {
t.Errorf("Duration.UnmarshalJSON() = %q, want %q", got, tt.want)
}
})
}
}

0 comments on commit 18bfc8f

Please sign in to comment.