Skip to content

CUE: Investigate dynamic fields. #886

@spinillos

Description

@spinillos

Cue parser is currently managing structs as close ones. Adding [string]: _ or ... to declare the struct open is completely ignored, forcing people to add extra code to cover this issue.

Output example:

type AnnotationQuery struct {
	// Typed fields
	Name       string        `json:"name"`
	Datasource DataSourceRef `json:"datasource"`
	Enable     bool          `json:"enable"`
	IconColor  string        `json:"iconColor"`

	// Extra fields storage (not serialized directly)
	ExtraFields map[string]any `json:"-"`
}

func (a *AnnotationQuery) UnmarshalJSON(data []byte) error {
	// First unmarshal into a map to capture everything
	var raw map[string]json.RawMessage
	if err := json.Unmarshal(data, &raw); err != nil {
		return err
	}

	// Unmarshal known fields
	if v, ok := raw["name"]; ok {
		json.Unmarshal(v, &a.Name)
		delete(raw, "name")
	}
	if v, ok := raw["datasource"]; ok {
		json.Unmarshal(v, &a.Datasource)
		delete(raw, "datasource")
	}
	// ... handle other known fields ...

	// Everything left goes into ExtraFields
	a.ExtraFields = make(map[string]any)
	for key, val := range raw {
		var v any
		json.Unmarshal(val, &v)
		a.ExtraFields[key] = v
	}

	return nil
}

func (a AnnotationQuery) MarshalJSON() ([]byte, error) {
	// Start with typed fields
	type Alias AnnotationQuery // prevent recursion
	base, _ := json.Marshal((Alias)(a))

	var baseMap map[string]any
	json.Unmarshal(base, &baseMap)

	// Merge in extra fields
	for k, v := range a.ExtraFields {
		baseMap[k] = v
	}

	return json.Marshal(baseMap)
}

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions