(ctx context.Context, webCall WebCallType)
| 315 | } |
| 316 | |
| 317 | func CallService(ctx context.Context, webCall WebCallType) *WebReturnType { |
| 318 | svcObj := ServiceMap[webCall.Service] |
| 319 | if svcObj == nil { |
| 320 | return webErrorRtn(fmt.Errorf("invalid service: %q", webCall.Service)) |
| 321 | } |
| 322 | method := reflect.ValueOf(svcObj).MethodByName(webCall.Method) |
| 323 | if !method.IsValid() { |
| 324 | return webErrorRtn(fmt.Errorf("invalid method: %s.%s", webCall.Service, webCall.Method)) |
| 325 | } |
| 326 | var valueArgs []reflect.Value |
| 327 | argIdx := 0 |
| 328 | for idx := 0; idx < method.Type().NumIn(); idx++ { |
| 329 | argType := method.Type().In(idx) |
| 330 | if idx == 0 && argType == contextRType { |
| 331 | valueArgs = append(valueArgs, reflect.ValueOf(ctx)) |
| 332 | continue |
| 333 | } |
| 334 | if argType == uiContextRType { |
| 335 | if webCall.UIContext == nil { |
| 336 | return webErrorRtn(fmt.Errorf("missing UIContext for %s.%s", webCall.Service, webCall.Method)) |
| 337 | } |
| 338 | valueArgs = append(valueArgs, reflect.ValueOf(*webCall.UIContext)) |
| 339 | continue |
| 340 | } |
| 341 | if argIdx >= len(webCall.Args) { |
| 342 | return webErrorRtn(fmt.Errorf("not enough arguments passed %s.%s idx:%d (type %T)", webCall.Service, webCall.Method, idx, argType)) |
| 343 | } |
| 344 | nativeArg, err := convertArgument(argType, webCall.Args[argIdx]) |
| 345 | if err != nil { |
| 346 | return webErrorRtn(fmt.Errorf("cannot convert argument %s.%s type:%T idx:%d error:%v", webCall.Service, webCall.Method, argType, idx, err)) |
| 347 | } |
| 348 | valueArgs = append(valueArgs, reflect.ValueOf(nativeArg)) |
| 349 | argIdx++ |
| 350 | } |
| 351 | retValArr := method.Call(valueArgs) |
| 352 | return convertReturnValues(retValArr) |
| 353 | } |
| 354 | |
| 355 | // ValidateServiceArg validates the argument type for a service method |
| 356 | // does not allow interfaces (and the obvious invalid types) |
no test coverage detected