Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: don't design interfaces, discover them. #111

Merged
merged 2 commits into from
Sep 6, 2024
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
3 changes: 3 additions & 0 deletions src/wasm/activity-service/activity/activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package activity

import (
"errors"
"strconv"
"time"

Expand All @@ -25,6 +26,8 @@ import (
"github.com/muktihari/fit/proto"
)

var ErrNoActivity = errors.New("no activity")

// Activity is an activity. It use FIT SDK's structure as its base since FIT is currently the most advance format.
type Activity struct {
Creator Creator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ import (
"github.com/muktihari/fit/proto"
"github.com/openivity/activity-service/activity"
"github.com/openivity/activity-service/mem"
"github.com/openivity/activity-service/service"
"golang.org/x/exp/slices"
)

var _ activity.Service = (*service)(nil)
var _ service.DecodeEncoder = (*DecodeEncoder)(nil)

var decoderPool = sync.Pool{New: func() any { return decoder.New(nil) }}
var encoderPool = sync.Pool{New: func() any { return encoder.New(nil) }}

type service struct {
type DecodeEncoder struct {
preprocessor *activity.Preprocessor
}

// NewService creates new FIT service.
func NewService(preproc *activity.Preprocessor) activity.Service {
return &service{
// NewDecodeEncoder creates new FIT decode-encoder.
func NewDecodeEncoder(preproc *activity.Preprocessor) *DecodeEncoder {
return &DecodeEncoder{
preprocessor: preproc,
}
}

func (s *service) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
func (s *DecodeEncoder) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
lis := filedef.NewListener()
defer lis.Close()

Expand Down Expand Up @@ -114,7 +115,7 @@ func (s *service) Decode(ctx context.Context, r io.Reader) ([]activity.Activity,
return activities, nil
}

func (s *service) convertToActivity(activityFile *filedef.Activity) activity.Activity {
func (s *DecodeEncoder) convertToActivity(activityFile *filedef.Activity) activity.Activity {
var timezone int8
if activityFile.Activity != nil {
localTimestamp := activityFile.Activity.LocalTimestamp
Expand Down Expand Up @@ -221,7 +222,7 @@ func (s *service) convertToActivity(activityFile *filedef.Activity) activity.Act
}

// recalculateSummary recalculates values based on Laps and Records.
func (s *service) recalculateSummary(ses *activity.Session) {
func (s *DecodeEncoder) recalculateSummary(ses *activity.Session) {
records := slices.Clone(ses.Records)
if len(ses.Laps) == 1 { // Ensure lap's time windows match with session, FIT produces by Strava contains wrong time.
ses.Laps[0].StartTime = ses.StartTime
Expand Down Expand Up @@ -250,7 +251,7 @@ func (s *service) recalculateSummary(ses *activity.Session) {
ses.Summarize()
}

func (s *service) handleUnrelatedMessages(activityFile *filedef.Activity) []proto.Message {
func (s *DecodeEncoder) handleUnrelatedMessages(activityFile *filedef.Activity) []proto.Message {
size := len(activityFile.DeveloperDataIds) +
len(activityFile.FieldDescriptions) +
len(activityFile.DeviceInfos) +
Expand Down Expand Up @@ -312,7 +313,7 @@ func (s *service) handleUnrelatedMessages(activityFile *filedef.Activity) []prot
return unrelatedMessages
}

func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
func (s *DecodeEncoder) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
buf := mem.GetBuffer()
defer mem.PutBuffer(buf)

Expand Down Expand Up @@ -340,7 +341,7 @@ func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([
return bs, nil
}

func (s *service) makeLastSummary(a *activity.Activity) {
func (s *DecodeEncoder) makeLastSummary(a *activity.Activity) {
var lastTimestamp time.Time
for i := len(a.Sessions) - 1; i >= 0; i-- {
ses := a.Sessions[i]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/openivity/activity-service/activity"
"github.com/openivity/activity-service/activity/gpx/schema"
"github.com/openivity/activity-service/mem"
"github.com/openivity/activity-service/service"
"github.com/openivity/activity-service/strutils"
"github.com/openivity/activity-service/xmlutils"
"golang.org/x/exp/slices"
Expand All @@ -35,18 +36,18 @@ const (
metadataLink = "https://openivity.github.io"
)

var _ activity.Service = (*service)(nil)
var _ service.DecodeEncoder = (*DecodeEncoder)(nil)

type service struct {
type DecodeEncoder struct {
preprocessor *activity.Preprocessor
}

// NewService creates new GPX service.
func NewService(preproc *activity.Preprocessor) activity.Service {
return &service{preprocessor: preproc}
// NewDecodeEncoder creates new GPX decode-encoder.
func NewDecodeEncoder(preproc *activity.Preprocessor) *DecodeEncoder {
return &DecodeEncoder{preprocessor: preproc}
}

func (s *service) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
func (s *DecodeEncoder) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
tok := xmltokenizer.New(r)

var gpx schema.GPX
Expand Down Expand Up @@ -150,7 +151,7 @@ loop:
return []activity.Activity{act}, nil
}

func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
func (s *DecodeEncoder) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
bs := make([][]byte, len(activities))

buf := mem.GetBuffer()
Expand All @@ -171,7 +172,7 @@ func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([
return bs, nil
}

func (s *service) convertActivityToGPX(act *activity.Activity) schema.GPX {
func (s *DecodeEncoder) convertActivityToGPX(act *activity.Activity) schema.GPX {
gpx := schema.GPX{
Creator: act.Creator.Name,
Metadata: schema.Metadata{
Expand Down
32 changes: 0 additions & 32 deletions src/wasm/activity-service/activity/service.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/openivity/activity-service/activity"
"github.com/openivity/activity-service/activity/tcx/schema"
"github.com/openivity/activity-service/mem"
"github.com/openivity/activity-service/service"
"github.com/openivity/activity-service/strutils"
"github.com/openivity/activity-service/xmlutils"
"golang.org/x/exp/slices"
Expand All @@ -36,18 +37,18 @@ const (
applicationName = "openitivy.github.io"
)

var _ activity.Service = (*service)(nil)
var _ service.DecodeEncoder = (*DecodeEncoder)(nil)

type service struct {
type DecodeEncoder struct {
preprocessor *activity.Preprocessor
}

// NewService creates new TCX service.
func NewService(preproc *activity.Preprocessor) activity.Service {
return &service{preprocessor: preproc}
// NewDecodeEncoder creates new TCX decode-encoder.
func NewDecodeEncoder(preproc *activity.Preprocessor) *DecodeEncoder {
return &DecodeEncoder{preprocessor: preproc}
}

func (s *service) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
func (s *DecodeEncoder) Decode(ctx context.Context, r io.Reader) ([]activity.Activity, error) {
tok := xmltokenizer.New(r)

var tcx schema.TCX
Expand Down Expand Up @@ -188,7 +189,7 @@ loop:
return []activity.Activity{act}, nil
}

func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
func (s *DecodeEncoder) Encode(ctx context.Context, activities []activity.Activity) ([][]byte, error) {
bs := make([][]byte, len(activities))

buf := mem.GetBuffer()
Expand All @@ -206,7 +207,7 @@ func (s *service) Encode(ctx context.Context, activities []activity.Activity) ([
return bs, nil
}

func (s *service) convertActivityToTCX(act *activity.Activity) schema.TCX {
func (s *DecodeEncoder) convertActivityToTCX(act *activity.Activity) schema.TCX {
tcx := schema.TCX{
Author: &schema.Application{
Name: applicationName,
Expand Down
24 changes: 10 additions & 14 deletions src/wasm/activity-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,12 @@ var manufacturerJson []byte
func main() {
preproc := activity.NewPreprocessor()

fs := fit.NewService(preproc)
gs := gpx.NewService(preproc)
ts := tcx.NewService(preproc)

manufacturers := makeManufacturers()

svc := service.New(fs, gs, ts, manufacturers)
svc := service.New(
fit.NewDecodeEncoder(preproc),
gpx.NewDecodeEncoder(preproc),
tcx.NewDecodeEncoder(preproc),
makeManufacturers(),
)
muktihari marked this conversation as resolved.
Show resolved Hide resolved

js.Global().Set("decode", createDecodeFunc(svc))
js.Global().Set("encode", createEncodeFunc(svc))
Expand Down Expand Up @@ -124,7 +123,7 @@ func makeManufacturers() map[typedef.Manufacturer]activity.Manufacturer {
return manufacturers
}

func createDecodeFunc(s service.Service) js.Func {
func createDecodeFunc(s *service.Service) js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) any {
input := args[0] // input is an Array<Uint8Array>
if input.Length() == 0 {
Expand All @@ -140,7 +139,6 @@ func createDecodeFunc(s service.Service) js.Func {
}

result := s.Decode(context.Background(), rs)

decodedActivities = result.Activities

buf := mem.GetBuffer()
Expand All @@ -152,7 +150,7 @@ func createDecodeFunc(s service.Service) js.Func {
})
}

func createEncodeFunc(svc service.Service) js.Func {
func createEncodeFunc(svc *service.Service) js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) any {
input := args[0] // input is an JSON string
if input.Length() == 0 {
Expand All @@ -169,11 +167,9 @@ func createEncodeFunc(svc service.Service) js.Func {
}

encodeSpec.Activities = cloneActivities(decodedActivities)

elapsed := time.Since(begin)

result := svc.Encode(context.Background(), encodeSpec)

result.DeserializeInputTook = elapsed

buf := mem.GetBuffer()
Expand All @@ -185,15 +181,15 @@ func createEncodeFunc(svc service.Service) js.Func {
})
}

func createManufacturerListFunc(svc service.Service) js.Func {
func createManufacturerListFunc(svc *service.Service) js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) any {
manufacturerList := svc.ManufacturerList()
b := manufacturerList.MarshalAppendJSON(make([]byte, 0, 50<<10))
return string(b)
})
}

func createSportListFunc(svc service.Service) js.Func {
func createSportListFunc(svc *service.Service) js.Func {
return js.FuncOf(func(this js.Value, args []js.Value) any {
sportList := svc.SportList()
b := sportList.MarshalAppendJSON(make([]byte, 0, 8<<10))
Expand Down
Loading
Loading