public function castValue($field_name, $value)
    {
        if ($value === null) {
            return null; // NULL remains NULL
        }

        switch ($this->getTypeByFieldName($field_name)) {
            case self::CAST_INT:
                return (int) $value;
            case self::CAST_FLOAT:
                return (float) $value;
            case self::CAST_STRING:
                return (string) $value;
            case self::CAST_BOOL:
                return (bool) $value;
            case self::CAST_DATE:
                return new DateValue($value, 'UTC');
            case self::CAST_DATETIME:
                return new DateTimeValue($value, 'UTC');
            case self::CAST_JSON:
                if (empty($value)) {
                    return null;
                } else {
                    $result = json_decode($value, true);

                    if (empty($result) && json_last_error()) {
                        throw new RuntimeException('Failed to parse JSON. Reason: ' . json_last_error_msg(), json_last_error());
                    }

                    return $result;
                }
            default:
                return (string) $value;
        }
    }