-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add RouteContext.State to mark data only available for event receiver…
…s without a bounded template
- Loading branch information
Showing
6 changed files
with
228 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package fir | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"reflect" | ||
|
||
"github.com/fatih/structs" | ||
) | ||
|
||
type routeData map[string]any | ||
|
||
func (r *routeData) Error() string { | ||
b, _ := json.Marshal(r) | ||
return string(b) | ||
} | ||
|
||
type stateData map[string]any | ||
|
||
func (r *stateData) Error() string { | ||
b, _ := json.Marshal(r) | ||
return string(b) | ||
} | ||
|
||
type routeDataWithState struct { | ||
routeData *routeData | ||
stateData *stateData | ||
} | ||
|
||
func (r *routeDataWithState) Error() string { | ||
b1, _ := json.Marshal(r.routeData) | ||
b2, _ := json.Marshal(r.stateData) | ||
return fmt.Sprintf("routeData: %s\n stateData: %s", string(b1), string(b2)) | ||
} | ||
|
||
func buildData(stateOnly bool, dataset ...any) error { | ||
if len(dataset) == 0 { | ||
return nil | ||
} | ||
|
||
m := make(map[string]any) | ||
hasState := false | ||
state := make(stateData) | ||
|
||
for _, data := range dataset { | ||
if data == nil { | ||
continue | ||
} | ||
if sv, ok := data.(*stateData); ok { | ||
hasState = true | ||
for k, v := range *sv { | ||
state[k] = v | ||
m[k] = v | ||
} | ||
} | ||
val := reflect.ValueOf(data) | ||
|
||
if val.Kind() == reflect.Ptr { | ||
el := val.Elem() // dereference the pointer | ||
if el.Kind() == reflect.Struct { | ||
for k, v := range structs.Map(data) { | ||
m[k] = v | ||
} | ||
} | ||
} else if val.Kind() == reflect.Struct { | ||
for k, v := range structs.Map(data) { | ||
m[k] = v | ||
} | ||
} else if val.Kind() == reflect.Map { | ||
ms, ok := data.(map[string]any) | ||
if !ok { | ||
return errors.New("data must be a map[string]any , struct or pointer to a struct") | ||
} | ||
|
||
for k, v := range ms { | ||
m[k] = v | ||
} | ||
} else { | ||
return errors.New("data must be a map[string]any , struct or pointer to a struct") | ||
} | ||
} | ||
|
||
if stateOnly { | ||
t := stateData(m) | ||
return &t | ||
} | ||
|
||
if hasState { | ||
r := routeData(m) | ||
t := routeDataWithState{ | ||
routeData: &r, | ||
stateData: &state, | ||
} | ||
return &t | ||
} | ||
|
||
r := routeData(m) | ||
return &r | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package fir | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
type TestData struct { | ||
Name string | ||
Age int | ||
} | ||
|
||
func TestBuildData(t *testing.T) { | ||
// Test case 1: No dataset provided | ||
err := buildData(false) | ||
if err != nil { | ||
t.Errorf("Expected nil error, got: %v", err) | ||
} | ||
|
||
// Test case 2: Only routeData provided | ||
data := map[string]any{"key": "value"} | ||
err = buildData(false, data) | ||
if err == nil { | ||
t.Errorf("Expected error, got: %v", err) | ||
} | ||
r, ok := err.(*routeData) | ||
if !ok { | ||
t.Errorf("Expected error type *routeData, got: %v", reflect.TypeOf(err)) | ||
} | ||
if !reflect.DeepEqual(*r, routeData{"key": "value"}) { | ||
t.Errorf("Expected error value %v, got: %v", data, *r) | ||
} | ||
|
||
// Test case 2: Only stateData provided | ||
err = buildData(true, data) | ||
if err == nil { | ||
t.Errorf("Expected error, got: %v", err) | ||
} | ||
s, ok := err.(*stateData) | ||
if !ok { | ||
t.Errorf("Expected error type *stateData, got: %v", reflect.TypeOf(err)) | ||
} | ||
if !reflect.DeepEqual(*s, stateData{"key": "value"}) { | ||
t.Errorf("Expected error value %v, got: %v", data, *s) | ||
} | ||
|
||
// Test case 3: Both routeData and stateData provided | ||
err = buildData(false, data, buildData(true, map[string]any{"key1": "value1"})) | ||
if err == nil { | ||
t.Errorf("Expected error, got: %v", err) | ||
} | ||
rs, ok := err.(*routeDataWithState) | ||
if !ok { | ||
t.Errorf("Expected error type *routeDataWithState, got: %v", reflect.TypeOf(err)) | ||
} | ||
expectedRouteData := routeData{"key": "value", "key1": "value1"} | ||
if !reflect.DeepEqual(*rs.routeData, expectedRouteData) { | ||
t.Errorf("Expected error value %v, got: %v", expectedRouteData, *rs.routeData) | ||
} | ||
if !reflect.DeepEqual(*rs.stateData, stateData{"key1": "value1"}) { | ||
t.Errorf("Expected error value %v, got: %v", data, *rs.stateData) | ||
} | ||
|
||
} |