OneOf creates a union type from a name and a list of attributes. OneOf may be used wherever Attribute can. OneOf takes a name as first argument, a description as optional second argument and a function that lists the union types as last argument. Example: var PetOwner = Type("PetOwner", func()
(name string, args ...any)
| 219 | // }) |
| 220 | // }) |
| 221 | func OneOf(name string, args ...any) { |
| 222 | if len(args) == 0 { |
| 223 | eval.TooFewArgError() |
| 224 | return |
| 225 | } |
| 226 | if len(args) > 2 { |
| 227 | eval.TooManyArgError() |
| 228 | return |
| 229 | } |
| 230 | fn, ok := args[len(args)-1].(func()) |
| 231 | if !ok { |
| 232 | eval.InvalidArgError("function", args[len(args)-1]) |
| 233 | } |
| 234 | var desc string |
| 235 | if len(args) > 1 { |
| 236 | desc, ok = args[0].(string) |
| 237 | if !ok { |
| 238 | eval.InvalidArgError("string", args[0]) |
| 239 | } |
| 240 | } |
| 241 | Attribute(name, &expr.Union{TypeName: name}, desc, fn) |
| 242 | |
| 243 | // Extract and validate oneof:type:field and oneof:value:field meta tags |
| 244 | var parent *expr.AttributeExpr |
| 245 | switch def := eval.Current().(type) { |
| 246 | case *expr.AttributeExpr: |
| 247 | parent = def |
| 248 | case expr.CompositeExpr: |
| 249 | parent = def.Attribute() |
| 250 | default: |
| 251 | return |
| 252 | } |
| 253 | if parent == nil { |
| 254 | return |
| 255 | } |
| 256 | |
| 257 | // Find the union attribute we just created |
| 258 | attr := parent.Find(name) |
| 259 | if attr == nil || attr.Meta == nil { |
| 260 | return |
| 261 | } |
| 262 | |
| 263 | union, ok := attr.Type.(*expr.Union) |
| 264 | if !ok { |
| 265 | return |
| 266 | } |
| 267 | |
| 268 | // Extract type key from meta |
| 269 | if typeKeys, ok := attr.Meta["oneof:type:field"]; ok && len(typeKeys) > 0 { |
| 270 | typeKey := typeKeys[0] |
| 271 | if typeKey == "" { |
| 272 | eval.ReportError("oneof:type:field meta cannot be empty") |
| 273 | return |
| 274 | } |
| 275 | union.TypeKey = typeKey |
| 276 | } |
| 277 | |
| 278 | // Extract value key from meta |