(cfunc any)
| 234 | } |
| 235 | |
| 236 | func validateCFunc(cfunc any) error { |
| 237 | if cfunc == nil { |
| 238 | return fmt.Errorf("Component function cannot b nil") |
| 239 | } |
| 240 | rval := reflect.ValueOf(cfunc) |
| 241 | if rval.Kind() != reflect.Func { |
| 242 | return fmt.Errorf("Component function must be a function") |
| 243 | } |
| 244 | rtype := rval.Type() |
| 245 | if rtype.NumIn() != 1 { |
| 246 | return fmt.Errorf("Component function must take exactly 1 argument") |
| 247 | } |
| 248 | if rtype.NumOut() != 1 { |
| 249 | return fmt.Errorf("Component function must return exactly 1 value") |
| 250 | } |
| 251 | // first argument can be a map[string]any, or a struct, or ptr to struct (we'll reflect the value into it) |
| 252 | arg1Type := rtype.In(0) |
| 253 | if arg1Type.Kind() == reflect.Ptr { |
| 254 | arg1Type = arg1Type.Elem() |
| 255 | } |
| 256 | if arg1Type.Kind() == reflect.Map { |
| 257 | if arg1Type.Key().Kind() != reflect.String || |
| 258 | !(arg1Type.Elem().Kind() == reflect.Interface && arg1Type.Elem().NumMethod() == 0) { |
| 259 | return fmt.Errorf("Map argument must be map[string]any") |
| 260 | } |
| 261 | } else if arg1Type.Kind() != reflect.Struct && |
| 262 | !(arg1Type.Kind() == reflect.Interface && arg1Type.NumMethod() == 0) { |
| 263 | return fmt.Errorf("Component function argument must be map[string]any, struct, or any") |
| 264 | } |
| 265 | return nil |
| 266 | } |
| 267 | |
| 268 | func (r *RootElem) RegisterComponent(name string, cfunc any) error { |
| 269 | if err := validateCFunc(cfunc); err != nil { |
no test coverage detected