Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package core

import (
"encoding/json"
"errors"
"strings"
)

// Backward-compatible integer constants kept as-is.
const (
// PlatFormIos constant is 1 for iOS
PlatFormIos = iota + 1
Expand All @@ -9,9 +16,118 @@ const (
PlatFormHuawei
)

// Log block string constants (backward-compatible)
const (
// SucceededPush is log block
SucceededPush = "succeeded-push"
// FailedPush is log block
FailedPush = "failed-push"
)

// Platform is a typed enum for push target platforms.
// This complements the existing integer constants.
type Platform uint8

const (
// Typed equivalents of platform values.
PlatformIOS Platform = Platform(PlatFormIos)
PlatformAndroid Platform = Platform(PlatFormAndroid)
PlatformHuawei Platform = Platform(PlatFormHuawei)
)

// String returns a stable lowercase name for the platform.
func (p Platform) String() string {
switch p {
case PlatformIOS:
return "ios"
case PlatformAndroid:
return "android"
case PlatformHuawei:
return "huawei"
default:
return "unknown"
}
}

// IsValid reports whether the platform value is supported.
func (p Platform) IsValid() bool {
return p == PlatformIOS || p == PlatformAndroid || p == PlatformHuawei
}

// ParsePlatform parses a string (case-insensitive) into a Platform.
func ParsePlatform(s string) (Platform, error) {
switch strings.ToLower(strings.TrimSpace(s)) {
case "ios":
return PlatformIOS, nil
case "android":
return PlatformAndroid, nil
case "huawei":
return PlatformHuawei, nil
default:
return 0, errors.New("unknown platform: " + s)
}
}

// MarshalText encodes Platform as its string form.
func (p Platform) MarshalText() ([]byte, error) {
if !p.IsValid() {
return nil, errors.New("invalid platform")
}
return []byte(p.String()), nil
}

// UnmarshalText decodes Platform from its string form.
func (p *Platform) UnmarshalText(text []byte) error {
v, err := ParsePlatform(string(text))
if err != nil {
return err
}
*p = v
return nil
}

// MarshalJSON encodes Platform as a JSON string.
func (p Platform) MarshalJSON() ([]byte, error) {
if !p.IsValid() {
return nil, errors.New("invalid platform")
}
return json.Marshal(p.String())
}

// UnmarshalJSON decodes Platform from a JSON string or legacy number.
func (p *Platform) UnmarshalJSON(data []byte) error {
// Try string first.
var s string
if err := json.Unmarshal(data, &s); err == nil {
return p.UnmarshalText([]byte(s))
}
// Fallback to legacy numeric values 1/2/3.
var n int
if err := json.Unmarshal(data, &n); err == nil {
switch n {
case PlatFormIos:
*p = PlatformIOS
return nil
case PlatFormAndroid:
*p = PlatformAndroid
return nil
case PlatFormHuawei:
*p = PlatformHuawei
return nil
}
}
return errors.New("invalid platform JSON")
}

// LogBlock is a typed alias for log block kinds.
type LogBlock string

const (
LogSucceededPush LogBlock = LogBlock(SucceededPush)
LogFailedPush LogBlock = LogBlock(FailedPush)
)

// IsValid checks a LogBlock value.
func (l LogBlock) IsValid() bool {
return l == LogSucceededPush || l == LogFailedPush
}
87 changes: 87 additions & 0 deletions core/core_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package core

import (
"encoding/json"
"testing"
)

func TestPlatformStringAndValidity(t *testing.T) {
cases := []struct {
p Platform
expected string
}{
{PlatformIOS, "ios"},
{PlatformAndroid, "android"},
{PlatformHuawei, "huawei"},
}

for _, c := range cases {
if !c.p.IsValid() {
t.Fatalf("expected %v to be valid", c.p)
}
if got := c.p.String(); got != c.expected {
t.Fatalf("String() mismatch: got %q want %q", got, c.expected)
}
}

if Platform(0).IsValid() {
t.Fatalf("expected zero value to be invalid")
}
}

func TestParsePlatform(t *testing.T) {
p, err := ParsePlatform(" IOS ")
if err != nil || p != PlatformIOS {
t.Fatalf("ParsePlatform ios failed: p=%v err=%v", p, err)
}
p, err = ParsePlatform("android")
if err != nil || p != PlatformAndroid {
t.Fatalf("ParsePlatform android failed: p=%v err=%v", p, err)
}
p, err = ParsePlatform("HuAwEi")
if err != nil || p != PlatformHuawei {
t.Fatalf("ParsePlatform huawei failed: p=%v err=%v", p, err)
}
if _, err = ParsePlatform("unknown"); err == nil {
t.Fatalf("expected error for unknown platform")
}
}

func TestPlatformTextMarshaling(t *testing.T) {
b, err := PlatformIOS.MarshalText()
if err != nil || string(b) != "ios" {
t.Fatalf("MarshalText: got %q err=%v", string(b), err)
}
var p Platform
if err := p.UnmarshalText([]byte("android")); err != nil || p != PlatformAndroid {
t.Fatalf("UnmarshalText: p=%v err=%v", p, err)
}
}

func TestPlatformJSONMarshaling(t *testing.T) {
b, err := json.Marshal(PlatformHuawei)
if err != nil || string(b) != "\"huawei\"" {
t.Fatalf("MarshalJSON: got %s err=%v", string(b), err)
}
var p Platform
if err := json.Unmarshal([]byte("\"ios\""), &p); err != nil || p != PlatformIOS {
t.Fatalf("UnmarshalJSON string: p=%v err=%v", p, err)
}
// legacy numeric values
if err := json.Unmarshal([]byte("2"), &p); err != nil || p != PlatformAndroid {
t.Fatalf("UnmarshalJSON legacy number: p=%v err=%v", p, err)
}
if err := json.Unmarshal([]byte("99"), &p); err == nil {
t.Fatalf("expected error for invalid numeric JSON")
}
}

func TestLogBlock(t *testing.T) {
if !LogSucceededPush.IsValid() || !LogFailedPush.IsValid() {
t.Fatalf("expected log blocks to be valid")
}
if LogBlock("x").IsValid() {
t.Fatalf("expected arbitrary value to be invalid")
}
}

Loading