diff --git a/pkg/api/api.go b/pkg/api/api.go index 43fe2167..fa47bf0f 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -2,11 +2,11 @@ package api import ( "context" - "encoding/json" "fmt" "github.com/GopeedLab/gopeed/pkg/api/model" "github.com/GopeedLab/gopeed/pkg/base" "github.com/GopeedLab/gopeed/pkg/download" + "github.com/GopeedLab/gopeed/pkg/util" "net" "net/http" "reflect" @@ -345,8 +345,8 @@ func (i *Instance) Close() *model.Result[any] { } type Request struct { - Method string `json:"method"` - Params []string `json:"params"` + Method string `json:"method"` + Params []any `json:"params"` } // Invoke support dynamic call method @@ -364,6 +364,11 @@ func Invoke(instance *Instance, request *Request) (ret any) { in := make([]reflect.Value, numIn) for i := 0; i < numIn; i++ { paramType := fn.Type().In(i) + arg := args[i] + if arg == nil { + in[i] = reflect.Zero(fn.Type().In(i)) + continue + } var param reflect.Value var paramPtr any if paramType.Kind() == reflect.Ptr { @@ -373,7 +378,7 @@ func Invoke(instance *Instance, request *Request) (ret any) { param = reflect.New(paramType).Elem() paramPtr = param.Addr().Interface() } - if err := json.Unmarshal([]byte(args[i]), paramPtr); err != nil { + if err := util.MapToStruct(arg, paramPtr); err != nil { panic(err) } in[i] = param diff --git a/pkg/api/api_test.go b/pkg/api/api_test.go index b21e2492..3bc46865 100644 --- a/pkg/api/api_test.go +++ b/pkg/api/api_test.go @@ -10,26 +10,20 @@ import ( var instance, _ = Create(nil) func TestInvoke(t *testing.T) { - doTestInvoke(t, "Info", []any{}) - doTestInvoke(t, "GetTasks", nil) - doTestInvoke(t, "GetTasks", []any{}) - doTestInvoke(t, "GetTasks", []any{nil}) - doTestInvoke(t, "GetTasks", []any{&download.TaskFilter{}}) + doTestInvoke(t, "Info", []any{}, model.CodeOk) + doTestInvoke(t, "Info1", []any{}, model.CodeError) + doTestInvoke(t, "CreateTask", []any{nil}, model.CodeError) + doTestInvoke(t, "GetTasks", nil, model.CodeError) + doTestInvoke(t, "GetTasks", []any{}, model.CodeError) + doTestInvoke(t, "GetTasks", []any{"{abc:123"}, model.CodeError) + doTestInvoke(t, "GetTasks", []any{&download.TaskFilter{}}, model.CodeOk) + doTestInvoke(t, "SwitchExtension", []any{"test", &model.SwitchExtension{Status: true}}, model.CodeError) } -func doTestInvoke(t *testing.T, method string, params []any) *model.Result[any] { - reqParams := make([]string, len(params)) - for i, p := range params { - bytes, err := json.Marshal(p) - if err != nil { - t.Fatal(err) - } - reqParams[i] = string(bytes) - } - +func doTestInvoke(t *testing.T, method string, params []any, expectCode model.RespCode) { result := Invoke(instance, &Request{ Method: method, - Params: reqParams, + Params: params, }) buf, err := json.Marshal(result) if err != nil { @@ -40,5 +34,8 @@ func doTestInvoke(t *testing.T, method string, params []any) *model.Result[any] if err := json.Unmarshal(buf, &res); err != nil { t.Fatal(err) } - return &res + + if res.Code != expectCode { + t.Fatalf("Invoke method [%s] failed, expect code [%d], got [%d], msg: %s", method, expectCode, res.Code, res.Msg) + } } diff --git a/ui/flutter/lib/api/entry/libgopeed_boot_native.dart b/ui/flutter/lib/api/entry/libgopeed_boot_native.dart index dd42d3cd..fa693d80 100644 --- a/ui/flutter/lib/api/entry/libgopeed_boot_native.dart +++ b/ui/flutter/lib/api/entry/libgopeed_boot_native.dart @@ -62,14 +62,7 @@ class LibgopeedBootNative List params, T Function(dynamic json)? fromJsonT, ) async { - final invokeRequest = InvokeRequest( - method: method, - params: params.map((e) { - if (e.toJson != null) { - return jsonEncode(e.toJson()); - } - return jsonEncode(e); - }).toList()); + final invokeRequest = InvokeRequest(method: method, params: params); final resp = await _libgopeedAbi.invoke(jsonEncode(invokeRequest)); final result = Result.fromJson(jsonDecode(resp), fromJsonT ??= (json) => null as T); @@ -172,7 +165,7 @@ class LibgopeedBootNative @override Future> getTasks(TaskFilter? filter) async { return _invoke>("GetTasks", _parseTaskFilter(filter), - (json) => json.map((e) => Task.fromJson(e)).toList()); + (json) => (json as List).map((e) => Task.fromJson(e)).toList()); } @override @@ -200,7 +193,7 @@ class LibgopeedBootNative @override Future> getExtensions() async { return _invoke>("GetExtensions", [], - (json) => json.map((e) => Extension.fromJson(e)).toList()); + (json) => (json as List).map((e) => Extension.fromJson(e)).toList()); } @override diff --git a/ui/flutter/lib/api/entry/libgopeed_boot_web.dart b/ui/flutter/lib/api/entry/libgopeed_boot_web.dart index 29e9d166..942e90e7 100644 --- a/ui/flutter/lib/api/entry/libgopeed_boot_web.dart +++ b/ui/flutter/lib/api/entry/libgopeed_boot_web.dart @@ -125,8 +125,7 @@ class LibgopeedBootWeb @override Future pauseTask(String id) async { - await _fetch( - () => _dio.put("$_apiPrefix/tasks/$id/pause", data: {}), null); + await _fetch(() => _dio.put("$_apiPrefix/tasks/$id/pause"), null); } @override @@ -139,8 +138,7 @@ class LibgopeedBootWeb @override Future continueTask(String id) async { - await _fetch( - () => _dio.put("$_apiPrefix/tasks/$id/continue", data: {}), null); + await _fetch(() => _dio.put("$_apiPrefix/tasks/$id/continue"), null); } @override diff --git a/ui/flutter/lib/api/native/model/invoke_request.dart b/ui/flutter/lib/api/native/model/invoke_request.dart index b697670e..56bee9df 100644 --- a/ui/flutter/lib/api/native/model/invoke_request.dart +++ b/ui/flutter/lib/api/native/model/invoke_request.dart @@ -5,7 +5,7 @@ part 'invoke_request.g.dart'; @JsonSerializable() class InvokeRequest { String method; - List params; + List params; InvokeRequest({ this.method = '',