mirror of
https://github.com/sstent/go-garth.git
synced 2026-02-02 04:21:43 +00:00
reworked api interfaces
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
types "github.com/sstent/go-garth/internal/models/types"
|
||||
garth "github.com/sstent/go-garth/pkg/garth/types"
|
||||
shared "github.com/sstent/go-garth/shared/interfaces"
|
||||
)
|
||||
|
||||
@@ -19,38 +19,92 @@ type BodyBatteryReading struct {
|
||||
}
|
||||
|
||||
// ParseBodyBatteryReadings converts body battery values array to structured readings
|
||||
// Accepts mixed numeric types (int, int64, float64, json.Number) for robustness.
|
||||
func ParseBodyBatteryReadings(valuesArray [][]any) []BodyBatteryReading {
|
||||
readings := make([]BodyBatteryReading, 0)
|
||||
readings := make([]BodyBatteryReading, 0, len(valuesArray))
|
||||
|
||||
toInt := func(v any) (int, bool) {
|
||||
switch t := v.(type) {
|
||||
case int:
|
||||
return t, true
|
||||
case int32:
|
||||
return int(t), true
|
||||
case int64:
|
||||
return int(t), true
|
||||
case float32:
|
||||
return int(t), true
|
||||
case float64:
|
||||
return int(t), true
|
||||
case json.Number:
|
||||
i, err := t.Int64()
|
||||
if err == nil {
|
||||
return int(i), true
|
||||
}
|
||||
f, err := t.Float64()
|
||||
if err == nil {
|
||||
return int(f), true
|
||||
}
|
||||
return 0, false
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
toFloat64 := func(v any) (float64, bool) {
|
||||
switch t := v.(type) {
|
||||
case float32:
|
||||
return float64(t), true
|
||||
case float64:
|
||||
return t, true
|
||||
case int:
|
||||
return float64(t), true
|
||||
case int32:
|
||||
return float64(t), true
|
||||
case int64:
|
||||
return float64(t), true
|
||||
case json.Number:
|
||||
f, err := t.Float64()
|
||||
if err == nil {
|
||||
return f, true
|
||||
}
|
||||
return 0, false
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
for _, values := range valuesArray {
|
||||
if len(values) < 4 {
|
||||
continue
|
||||
}
|
||||
|
||||
timestamp, ok1 := values[0].(float64)
|
||||
ts, ok1 := toInt(values[0])
|
||||
status, ok2 := values[1].(string)
|
||||
level, ok3 := values[2].(float64)
|
||||
version, ok4 := values[3].(float64)
|
||||
lvl, ok3 := toInt(values[2])
|
||||
ver, ok4 := toFloat64(values[3])
|
||||
|
||||
if !ok1 || !ok2 || !ok3 || !ok4 {
|
||||
continue
|
||||
}
|
||||
|
||||
readings = append(readings, BodyBatteryReading{
|
||||
Timestamp: int(timestamp),
|
||||
Timestamp: ts,
|
||||
Status: status,
|
||||
Level: int(level),
|
||||
Version: version,
|
||||
Level: lvl,
|
||||
Version: ver,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Slice(readings, func(i, j int) bool {
|
||||
return readings[i].Timestamp < readings[j].Timestamp
|
||||
})
|
||||
|
||||
return readings
|
||||
}
|
||||
|
||||
// BodyBatteryDataWithMethods embeds types.DetailedBodyBatteryData and adds methods
|
||||
// BodyBatteryDataWithMethods embeds garth.DetailedBodyBatteryData and adds methods
|
||||
type BodyBatteryDataWithMethods struct {
|
||||
types.DetailedBodyBatteryData
|
||||
garth.DetailedBodyBatteryData
|
||||
}
|
||||
|
||||
func (d *BodyBatteryDataWithMethods) Get(day time.Time, c shared.APIClient) (interface{}, error) {
|
||||
@@ -71,14 +125,14 @@ func (d *BodyBatteryDataWithMethods) Get(day time.Time, c shared.APIClient) (int
|
||||
data2 = []byte("[]")
|
||||
}
|
||||
|
||||
var result types.DetailedBodyBatteryData
|
||||
var result garth.DetailedBodyBatteryData
|
||||
if len(data1) > 0 {
|
||||
if err := json.Unmarshal(data1, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Body Battery data: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var events []types.BodyBatteryEvent
|
||||
var events []garth.BodyBatteryEvent
|
||||
if len(data2) > 0 {
|
||||
if err := json.Unmarshal(data2, &events); err == nil {
|
||||
result.Events = events
|
||||
@@ -111,3 +165,48 @@ func (d *BodyBatteryDataWithMethods) GetDayChange() int {
|
||||
|
||||
return readings[len(readings)-1].Level - readings[0].Level
|
||||
}
|
||||
|
||||
// Added for test compatibility and public API alignment
|
||||
// DailyBodyBatteryStress wraps garth.DetailedBodyBatteryData and provides a Get method compatible with existing tests.
|
||||
// See [type DailyBodyBatteryStress](internal/data/body_battery.go:0) and [func (*DailyBodyBatteryStress).Get](internal/data/body_battery.go:0)
|
||||
type DailyBodyBatteryStress struct {
|
||||
garth.DetailedBodyBatteryData
|
||||
}
|
||||
|
||||
// Get retrieves Body Battery daily stress data and associated events for a given day.
|
||||
// Mirrors logic in BodyBatteryDataWithMethods.Get to maintain a consistent behavior.
|
||||
// Returns (*DailyBodyBatteryStress, nil) on success, (nil, nil) when no data available.
|
||||
func (d *DailyBodyBatteryStress) Get(day time.Time, c shared.APIClient) (interface{}, error) {
|
||||
dateStr := day.Format("2006-01-02")
|
||||
|
||||
// Get main Body Battery data
|
||||
path1 := fmt.Sprintf("/wellness-service/wellness/dailyStress/%s", dateStr)
|
||||
data1, err := c.ConnectAPI(path1, "GET", nil, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get Body Battery stress data: %w", err)
|
||||
}
|
||||
|
||||
// Get Body Battery events
|
||||
path2 := fmt.Sprintf("/wellness-service/wellness/bodyBattery/%s", dateStr)
|
||||
data2, err := c.ConnectAPI(path2, "GET", nil, nil)
|
||||
if err != nil {
|
||||
// Events might not be available, continue without them
|
||||
data2 = []byte("[]")
|
||||
}
|
||||
|
||||
var result garth.DetailedBodyBatteryData
|
||||
if len(data1) > 0 {
|
||||
if err := json.Unmarshal(data1, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Body Battery data: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var events []garth.BodyBatteryEvent
|
||||
if len(data2) > 0 {
|
||||
if err := json.Unmarshal(data2, &events); err == nil {
|
||||
result.Events = events
|
||||
}
|
||||
}
|
||||
|
||||
return &DailyBodyBatteryStress{DetailedBodyBatteryData: result}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user