Files
go-garminconnect/internal/api/types.go
2025-08-28 14:43:18 -07:00

96 lines
2.3 KiB
Go

package api
import (
"encoding/json"
"fmt"
"time"
)
// APIError represents an error returned by the API
type APIError struct {
StatusCode int
Message string
}
func (e *APIError) Error() string {
return fmt.Sprintf("API request failed with status %d: %s", e.StatusCode, e.Message)
}
// Error types for API responses
type ErrNotFound struct{}
func (e ErrNotFound) Error() string { return "resource not found" }
type ErrBadRequest struct{}
func (e ErrBadRequest) Error() string { return "bad request" }
// Time represents a Garmin Connect time value
type Time time.Time
// IsZero checks if the time is zero value
func (t Time) IsZero() bool {
return time.Time(t).IsZero()
}
// After reports whether t is after u
func (t Time) After(u Time) bool {
return time.Time(t).After(time.Time(u))
}
// Format formats the time using the provided layout
func (t Time) Format(layout string) string {
return time.Time(t).Format(layout)
}
// UnmarshalJSON implements json.Unmarshaler interface
func (t *Time) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return err
}
// Try multiple time formats that Garmin might use
formats := []string{
"2006-01-02T15:04:05.000Z",
"2006-01-02T15:04:05Z",
"2006-01-02T15:04:05.000",
"2006-01-02T15:04:05",
time.RFC3339,
time.RFC3339Nano,
}
for _, format := range formats {
if parsedTime, err := time.Parse(format, s); err == nil {
*t = Time(parsedTime)
return nil
}
}
// If none of the formats work, try parsing as RFC3339
parsedTime, err := time.Parse(time.RFC3339, s)
if err != nil {
return err
}
*t = Time(parsedTime)
return nil
}
// MarshalJSON implements json.Marshaler interface
func (t Time) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Time(t).Format(time.RFC3339))
}
// BodyComposition represents body composition metrics from Garmin Connect
type BodyComposition struct {
BoneMass float64 `json:"boneMass"` // Grams
MuscleMass float64 `json:"muscleMass"` // Grams
BodyFat float64 `json:"bodyFat"` // Percentage
Hydration float64 `json:"hydration"` // Percentage
Timestamp Time `json:"timestamp"` // Measurement time
}
// BodyCompositionRequest defines parameters for body composition API requests
type BodyCompositionRequest struct {
StartDate Time `json:"startDate"`
EndDate Time `json:"endDate"`
}