Skip to content

Commit

Permalink
filterx: implement set_fields()
Browse files Browse the repository at this point in the history
If there are overrides defined for the field,
we first iterate through them, and if there is
an expression that successfully evaluated, we
set it.

If overrides were not effective, and the field
already has a value, we are done with this field,
we leave it as it is.

If, however it did not have a value, we iterate through
the defaults, like we did with the overrides, and set
the field accordingly.

Signed-off-by: Attila Szakacs <attila.szakacs@axoflow.com>
  • Loading branch information
alltilla committed Nov 28, 2024
1 parent acc9b3c commit 7ee0cbf
Showing 1 changed file with 75 additions and 2 deletions.
77 changes: 75 additions & 2 deletions lib/filterx/func-set-fields.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "filterx/func-set-fields.h"
#include "filterx/object-string.h"
#include "filterx/object-primitive.h"
#include "filterx/object-dict-interface.h"
#include "filterx/expr-literal.h"
#include "filterx/expr-literal-generator.h"
Expand Down Expand Up @@ -127,11 +128,83 @@ typedef struct FilterXFunctionSetFields_
GArray *fields;
} FilterXFunctionSetFields;

static gboolean
_set_with_fallbacks(FilterXObject *dict_unwrapped, FilterXObject *key, GPtrArray *values)
{
gboolean changed = FALSE;

if (!values || values->len == 0)
return changed;

for (guint i = 0; i < values->len; i++)
{
FilterXExpr *value = g_ptr_array_index(values, i);
FilterXObject *value_obj = filterx_expr_eval(value);
if (!value_obj)
{
filterx_eval_clear_errors();
continue;
}

FilterXObject *value_obj_cloned = filterx_object_clone(value_obj);
filterx_object_unref(value_obj);

if (!filterx_object_set_subscript(dict_unwrapped, key, &value_obj_cloned))
{
filterx_object_unref(value_obj_cloned);
continue;
}

filterx_object_unref(value_obj_cloned);
changed = TRUE;
break;
}

return changed;
}

static void
_process_field(Field *field, FilterXObject *dict_unwrapped)
{
gboolean changed = _set_with_fallbacks(dict_unwrapped, field->key, field->overrides);
if (changed)
return;

if (filterx_object_is_key_set(dict_unwrapped, field->key))
return;

_set_with_fallbacks(dict_unwrapped, field->key, field->defaults);
}

static FilterXObject *
_eval(FilterXExpr *s)
{
// TODO: implement
return NULL;
FilterXFunctionSetFields *self = (FilterXFunctionSetFields *) s;

gboolean success = FALSE;

FilterXObject *dict = filterx_expr_eval(self->dict);
if (!dict)
goto exit;

FilterXObject *dict_unwrapped = filterx_ref_unwrap_rw(dict);
if (!filterx_object_is_type(dict_unwrapped, &FILTERX_TYPE_NAME(dict)))
{
filterx_eval_push_error("First argument must be a dict. " FILTERX_FUNC_SET_FIELDS_USAGE, s, NULL);
goto exit;
}

for (guint i = 0; i < self->fields->len; i++)
{
Field *field = &g_array_index(self->fields, Field, i);
_process_field(field, dict_unwrapped);
}

success = TRUE;

exit:
filterx_object_unref(dict);
return success ? filterx_boolean_new(TRUE) : NULL;
}

static gboolean
Expand Down

0 comments on commit 7ee0cbf

Please sign in to comment.