func()

in pkg/log/structure/merger/merged.go [145:296]


func (d *StrategicMergedStructureData) Value(fieldName string) (any, error) {
	ty, err := d.Type()
	if err != nil {
		return nil, err
	}

	switch ty {
	case structuredata.StructuredTypeScalar:
		patchPolicy, err := d.readScalarAsString(d.patch, "$patch")
		if err == nil && patchPolicy == "delete" {
			return nil, nil
		}
		return d.patch.Value(fieldName)

	case structuredata.StructuredTypeMap:
		if fieldName == "" {
			return d, nil
		}
		patchPolicy, err := d.readScalarAsString(d.patch, "$patch")
		if err == nil && patchPolicy == "replace" {
			return d.patch.Value(fieldName)
		}
		retainKeysAttr, err := d.readStringArray(d.patch, "$retainKeys")
		if err == nil {
			kept := false
			for _, key := range retainKeysAttr {
				if key == fieldName {
					kept = true
					break
				}
			}
			if !kept {
				return fmt.Errorf("field not found:%s(patched by delete already)", fieldName), nil
			}
		}
		prevFound := false
		patchFound := false
		var patchValueStructure structuredata.StructureData
		var prevValueStructure structuredata.StructureData
		patchValue, err := d.patch.Value(fieldName)
		if err == nil {
			var convertible bool
			patchFound = true
			patchValueStructure, convertible = patchValue.(structuredata.StructureData)
			if !convertible {
				return nil, fmt.Errorf("unreachable. Map children was not the structure data")
			}
		}
		prevValue, err := d.prev.Value(fieldName)
		if err == nil {
			var convertible bool
			prevValueStructure, convertible = prevValue.(structuredata.StructureData)
			if !convertible {
				return nil, fmt.Errorf("unreachable. Map children was not the structure data")
			}
			prevValueType, err := prevValueStructure.Type()
			if err != nil {
				return nil, err
			}
			// Ignore if the previous value is nil
			if prevValueType == structuredata.StructuredTypeScalar {
				prevActualValue, err := prevValueStructure.Value("")
				if err != nil {
					return nil, err
				}
				if prevActualValue != nil {
					prevFound = true
				} else if !patchFound {
					return prevValueStructure, nil
				}
			} else {
				prevFound = true
			}
		}

		switch {
		case prevFound && patchFound:
			result := NewStrategicMergedStructureData(fmt.Sprintf("%s.%s", d.path, fieldName), prevValueStructure, patchValueStructure, d.mergeKeyResolver)
			deleteFromPrimitiveList, err := d.readArray(d.patch, fmt.Sprintf("$deleteFromPrimitiveList/%s", fieldName))
			if err == nil {
				result.deleteFromPrimitiveListDirective = &deleteFromPrimitiveListDirective{
					list: deleteFromPrimitiveList,
				}
			}
			setOrderElementList, err := d.readArray(d.patch, fmt.Sprintf("$setElementOrder/%s", fieldName))
			if err == nil {
				result.setElementOrderDirective = &setElementOrderDirective{
					list: setOrderElementList,
				}
			}
			return result, nil
		case prevFound:
			result := NewStrategicMergedStructureData(fmt.Sprintf("%s.%s", d.path, fieldName), prevValueStructure, prevValueStructure, d.mergeKeyResolver)
			deleteFromPrimitiveList, err := d.readArray(d.patch, fmt.Sprintf("$deleteFromPrimitiveList/%s", fieldName))
			if err == nil {
				result.deleteFromPrimitiveListDirective = &deleteFromPrimitiveListDirective{
					list: deleteFromPrimitiveList,
				}
			}
			setOrderElementList, err := d.readArray(d.patch, fmt.Sprintf("$setElementOrder/%s", fieldName))
			if err == nil {
				result.setElementOrderDirective = &setElementOrderDirective{
					list: setOrderElementList,
				}
			}
			return result, nil
		case patchFound:
			result := NewStrategicMergedStructureData(fmt.Sprintf("%s.%s", d.path, fieldName), patchValueStructure, patchValueStructure, d.mergeKeyResolver)
			deleteFromPrimitiveList, err := d.readArray(d.patch, fmt.Sprintf("$deleteFromPrimitiveList/%s", fieldName))
			if err == nil {
				result.deleteFromPrimitiveListDirective = &deleteFromPrimitiveListDirective{
					list: deleteFromPrimitiveList,
				}
			}
			setOrderElementList, err := d.readArray(d.patch, fmt.Sprintf("$setElementOrder/%s", fieldName))
			if err == nil {
				result.setElementOrderDirective = &setElementOrderDirective{
					list: setOrderElementList,
				}
			}
			return result, nil
		default:
			return nil, fmt.Errorf("field not found:%s", fieldName)
		}

	case structuredata.StructuredTypeArray:
		if fieldName == "" {
			return d, nil
		}
		if d.arrayMergeResultSourceCache == nil {
			err := d.buildArrayMergeResultSourceCache()
			if err != nil {
				return nil, err
			}
		}
		index, err := strconv.Atoi(fieldName)
		if err != nil {
			return nil, err
		}
		if index < 0 || index >= len(d.arrayMergeResultSourceCache.References) {
			return nil, fmt.Errorf("index out of range")
		}
		ref := d.arrayMergeResultSourceCache.References[index]
		if ref.Index == "" {
			return ref.From, nil
		}
		return ref.From.Value(ref.Index)

	default:
		return nil, fmt.Errorf("unsupported type to merge")
	}
}