Skip to content

Commit f94bd70

Browse files
authored
feat: add support for dynamic partitioning config (#286)
1 parent c174ab7 commit f94bd70

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

channel_config.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
package stream_chat
22

3+
import (
4+
"strconv"
5+
"time"
6+
)
7+
38
// ChannelConfig is the configuration for a channel.
49
type ChannelConfig struct {
510
Name string `json:"name"`
@@ -34,6 +39,47 @@ type ChannelConfig struct {
3439
BlockList string `json:"blocklist"`
3540
BlockListBehavior modBehaviour `json:"blocklist_behavior"`
3641
AutomodThresholds *Thresholds `json:"automod_thresholds"`
42+
43+
// Dynamic Partitioning
44+
PartitionSize int `json:"partition_size,omitempty"`
45+
PartitionTTL *DurationString `json:"partition_ttl,omitempty"`
46+
}
47+
48+
// DurationString is a duration that's encoded to as a string in JSON.
49+
type DurationString time.Duration
50+
51+
// NewDurationString creates a pointer to a DurationString.
52+
func NewDurationString(d time.Duration) *DurationString {
53+
duration := DurationString(d)
54+
return &duration
55+
}
56+
57+
// MarshalJSON encodes the duration as a string such as "2h30m".
58+
func (d DurationString) MarshalJSON() ([]byte, error) {
59+
if d == 0 {
60+
return []byte("null"), nil
61+
}
62+
return []byte(`"` + time.Duration(d).String() + `"`), nil
63+
}
64+
65+
// String returns the duration as a string such as "2h30m".
66+
func (d DurationString) String() string {
67+
return time.Duration(d).String()
68+
}
69+
70+
// UnmarshalJSON decodes a duration from a string formatted as
71+
// [time.Duration.String()](https://golang.org/pkg/time/#Duration.String)
72+
func (d *DurationString) UnmarshalJSON(b []byte) error {
73+
s, err := strconv.Unquote(string(b))
74+
if err != nil {
75+
return err
76+
}
77+
dur, err := time.ParseDuration(s)
78+
if err != nil {
79+
return err
80+
}
81+
*d = DurationString(dur)
82+
return nil
3783
}
3884

3985
type LabelThresholds struct {

channel_config_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package stream_chat
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
"time"
7+
)
8+
9+
func TestDuration_MarshalJSON(t *testing.T) {
10+
tests := []struct {
11+
name string
12+
input DurationString
13+
want string
14+
}{
15+
{
16+
name: "Zero",
17+
input: DurationString(0),
18+
want: `null`,
19+
},
20+
{
21+
name: "Hours",
22+
input: DurationString(24 * time.Hour),
23+
want: `"24h0m0s"`,
24+
},
25+
{
26+
name: "Mixed",
27+
input: DurationString(24*time.Hour + 30*time.Minute + 15*time.Second),
28+
want: `"24h30m15s"`,
29+
},
30+
}
31+
32+
for _, tt := range tests {
33+
t.Run(tt.name, func(t *testing.T) {
34+
got, err := tt.input.MarshalJSON()
35+
if err != nil {
36+
t.Fatal(err)
37+
}
38+
if string(got) != tt.want {
39+
t.Errorf("Duration.MarshalJSON() = %q, want %q", string(got), tt.want)
40+
}
41+
})
42+
}
43+
}
44+
45+
func TestDuration_UnmarshalJSON(t *testing.T) {
46+
tests := []struct {
47+
name string
48+
input string
49+
want DurationString
50+
wantErr bool
51+
}{
52+
{
53+
name: "Hours",
54+
input: `"4h"`,
55+
want: DurationString(4 * time.Hour),
56+
},
57+
{
58+
name: "Mixed",
59+
input: `"2h30m"`,
60+
want: DurationString(2*time.Hour + 30*time.Minute),
61+
},
62+
{
63+
name: "Full",
64+
input: `"6h0m0s"`,
65+
want: DurationString(6 * time.Hour),
66+
},
67+
{
68+
name: "Invalid",
69+
input: "daily",
70+
wantErr: true,
71+
},
72+
}
73+
74+
for _, tt := range tests {
75+
t.Run(tt.name, func(t *testing.T) {
76+
var got DurationString
77+
err := json.Unmarshal([]byte(tt.input), &got)
78+
if (err != nil) != tt.wantErr {
79+
t.Fatalf("Error = %q, want error: %t", err, tt.wantErr)
80+
}
81+
if got.String() != tt.want.String() {
82+
t.Errorf("Duration.UnmarshalJSON() = %q, want %q", got, tt.want)
83+
}
84+
})
85+
}
86+
}

0 commit comments

Comments
 (0)