From 2b8b371daa8c63c7811937fb4674c900782d667f Mon Sep 17 00:00:00 2001 From: Mojtaba Arezoomand Date: Mon, 27 Apr 2026 09:51:09 +0330 Subject: [PATCH 1/3] fix: add defer statement to close response body in get method --- consts.go | 2 +- gosrm.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/consts.go b/consts.go index af00743..d4e7d27 100644 --- a/consts.go +++ b/consts.go @@ -43,7 +43,7 @@ const ( // CodeOK is returned when request could be processed as expected. CodeOK Code = "Ok" - //CodeInvalidUrl is returned when URL string is invalid. + // CodeInvalidUrl is returned when URL string is invalid. CodeInvalidUrl Code = "InvalidUrl" // CodeInvalidService is returned when service name is invalid. diff --git a/gosrm.go b/gosrm.go index 656bcc0..6e40c51 100644 --- a/gosrm.go +++ b/gosrm.go @@ -69,6 +69,7 @@ func (osrm OSRMClient) get(ctx context.Context, url string, out any) error { if err != nil { return err } + defer res.Body.Close() return json.NewDecoder(res.Body).Decode(out) } From 426a854285531b218b8cbc603d00333f4fe6555f Mon Sep 17 00:00:00 2001 From: Mojtaba Arezoomand Date: Mon, 27 Apr 2026 09:59:57 +0330 Subject: [PATCH 2/3] fix: update convertSliceToStr to use type constraints and improve test cases --- types.go | 2 +- utils.go | 55 +++++++++++++++++++++------------------------------ utils_test.go | 43 +++++++++++++++++++--------------------- 3 files changed, 44 insertions(+), 56 deletions(-) diff --git a/types.go b/types.go index 337d35d..9957552 100644 --- a/types.go +++ b/types.go @@ -123,7 +123,7 @@ type ( // BearingBefore is the clockwise angle from true north to the direction of travel immediately before the maneuver. BearingBefore float32 `json:"bearing_before"` - // BearingAfter is the clockwise angle from true north to the direction of travel immediately before the maneuver. + // BearingAfter is the clockwise angle from true north to the direction of travel immediately after the maneuver. BearingAfter float32 `json:"bearing_after"` // Type is a string indicating the type of maneuver. diff --git a/utils.go b/utils.go index fb489f7..939318f 100644 --- a/utils.go +++ b/utils.go @@ -6,41 +6,32 @@ import ( "strings" ) -// convertSliceToStr converts a slice of anything to {v}{sep}{v} representation of the slice. -func convertSliceToStr(s any, sep string) string { +// sliceElement is the type constraint for elements supported by convertSliceToStr. +type sliceElement interface { + uint16 | int64 | float32 | string | Approaches | Bearing | Coordinate +} + +// convertSliceToStr converts a slice to a {v}{sep}{v} string representation. +func convertSliceToStr[T sliceElement](s []T, sep string) string { var b bytes.Buffer - switch slice := s.(type) { - case []uint16: - for _, n := range slice { - b.WriteString(fmt.Sprintf("%d%s", n, sep)) - } - case []int64: - for _, n := range slice { - b.WriteString(fmt.Sprintf("%d%s", n, sep)) - } - case []float32: - for _, f := range slice { - b.WriteString(fmt.Sprintf("%f%s", f, sep)) - } - case []string: - for _, s := range slice { - b.WriteString(s + sep) - } - case []Approaches: - for _, approach := range slice { - b.WriteString(string(approach) + sep) - } - case []Bearing: - for _, bearing := range slice { - b.WriteString(fmt.Sprintf("%d,%d%s", bearing.Value, bearing.Range, sep)) - } - case []Coordinate: - for _, coor := range slice { - b.WriteString(fmt.Sprintf("%f,%f%s", coor[0], coor[1], sep)) + for _, v := range s { + switch val := any(v).(type) { + case uint16: + b.WriteString(fmt.Sprintf("%d%s", val, sep)) + case int64: + b.WriteString(fmt.Sprintf("%d%s", val, sep)) + case float32: + b.WriteString(fmt.Sprintf("%f%s", val, sep)) + case string: + b.WriteString(val + sep) + case Approaches: + b.WriteString(string(val) + sep) + case Bearing: + b.WriteString(fmt.Sprintf("%d,%d%s", val.Value, val.Range, sep)) + case Coordinate: + b.WriteString(fmt.Sprintf("%f,%f%s", val[0], val[1], sep)) } - default: - panic("unsupported type") } return strings.TrimSuffix(b.String(), sep) diff --git a/utils_test.go b/utils_test.go index 9a9b7a6..015595c 100644 --- a/utils_test.go +++ b/utils_test.go @@ -7,28 +7,25 @@ import ( ) func TestConvertSliceToStr(t *testing.T) { - assert.PanicsWithValue(t, "unsupported type", func() { - convertSliceToStr(nil, "") + t.Run("[]uint16", func(t *testing.T) { + assert.Equal(t, "1;2;3", convertSliceToStr([]uint16{1, 2, 3}, ";")) + }) + t.Run("[]int64", func(t *testing.T) { + assert.Equal(t, "1;2;3", convertSliceToStr([]int64{1, 2, 3}, ";")) + }) + t.Run("[]float32", func(t *testing.T) { + assert.Equal(t, "1.000000;2.000000;3.000000", convertSliceToStr([]float32{1, 2, 3}, ";")) + }) + t.Run("[]string", func(t *testing.T) { + assert.Equal(t, "abc;qwe", convertSliceToStr([]string{"abc", "qwe"}, ";")) + }) + t.Run("[]Approaches", func(t *testing.T) { + assert.Equal(t, "curb", convertSliceToStr([]Approaches{ApproachesCurb}, ";")) + }) + t.Run("[]Bearing", func(t *testing.T) { + assert.Equal(t, "150,100;200,100", convertSliceToStr([]Bearing{{Value: 150, Range: 100}, {Value: 200, Range: 100}}, ";")) + }) + t.Run("[]Coordinate", func(t *testing.T) { + assert.Equal(t, "1.000000,2.000000;10.000000,20.000000", convertSliceToStr([]Coordinate{{1, 2}, {10, 20}}, ";")) }) - - testCases := []struct { - expectedRes, name, sep string - input any - }{ - {name: "[]uint16", expectedRes: "1;2;3", sep: ";", input: []uint16{1, 2, 3}}, - {name: "[]int64", expectedRes: "1;2;3", sep: ";", input: []int64{1, 2, 3}}, - {name: "[]float32", expectedRes: "1.000000;2.000000;3.000000", sep: ";", input: []float32{1, 2, 3}}, - {name: "[]string", expectedRes: "abc;qwe", sep: ";", input: []string{"abc", "qwe"}}, - {name: "[]Approaches", expectedRes: "curb", sep: ";", input: []Approaches{ApproachesCurb}}, - {name: "[]Bearing", expectedRes: "150,100;200,100", sep: ";", input: []Bearing{{Value: 150, Range: 100}, {Value: 200, Range: 100}}}, - {name: "[]Coordinate", expectedRes: "1.000000,2.000000;10.000000,20.000000", sep: ";", input: []Coordinate{{1, 2}, {10, 20}}}, - } - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - res := convertSliceToStr(testCase.input, testCase.sep) - - assert.Equal(t, testCase.expectedRes, res) - }) - } } From 373de696d5f26ff17e56c50bc4267fa20ee449fa Mon Sep 17 00:00:00 2001 From: Mojtaba Arezoomand Date: Mon, 27 Apr 2026 10:10:23 +0330 Subject: [PATCH 3/3] fix: correct constant naming and improve comments for clarity --- consts.go | 4 ++-- options.go | 2 +- types.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/consts.go b/consts.go index d4e7d27..a38eb79 100644 --- a/consts.go +++ b/consts.go @@ -43,8 +43,8 @@ const ( // CodeOK is returned when request could be processed as expected. CodeOK Code = "Ok" - // CodeInvalidUrl is returned when URL string is invalid. - CodeInvalidUrl Code = "InvalidUrl" + // CodeInvalidURL is returned when URL string is invalid. + CodeInvalidURL Code = "InvalidUrl" // CodeInvalidService is returned when service name is invalid. CodeInvalidService Code = "InvalidService" diff --git a/options.go b/options.go index baec358..561dabc 100644 --- a/options.go +++ b/options.go @@ -98,7 +98,7 @@ func WithSources(sources []uint16) Option { }) } -// WithDestinations uses location with given index as destination. +// WithDestinations uses location with given index as destination. // If the slice is empty uses all. // Can be used in table service. func WithDestinations(destinations []uint16) Option { diff --git a/types.go b/types.go index 9957552..f22f4e6 100644 --- a/types.go +++ b/types.go @@ -209,7 +209,7 @@ type ( Nodes []uint64 `json:"nodes"` // Weight is the weights between each pair of coordinates. Does not include any turn costs. - Weight []float32 `json:"Weight"` + Weight []float32 `json:"weight"` // Speed is the convenience field, calculation of distance / duration rounded to one decimal place. Speed []float32 `json:"speed"`