Implement config_item_set_from()
This commit is contained in:
parent
d4deb31a17
commit
b4dab3489d
110
common.c
110
common.c
|
@ -534,7 +534,7 @@ struct config_schema
|
|||
bool (*validate) (struct config_item_ *, const struct config_item_ *);
|
||||
|
||||
/// The value has changed. Only appliable to objects.
|
||||
bool (*on_changed) (struct config_item_ *);
|
||||
void (*on_changed) (struct config_item_ *);
|
||||
|
||||
/// Free any resources located in "item->user_data"
|
||||
void (*on_destroy) (struct config_item_ *item);
|
||||
|
@ -542,12 +542,33 @@ struct config_schema
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
static void
|
||||
config_item_destroy (struct config_item_ *self)
|
||||
static const char *
|
||||
config_item_type_name (enum config_item_type type)
|
||||
{
|
||||
if (self->schema && self->schema->on_destroy)
|
||||
self->schema->on_destroy (self);
|
||||
switch (type)
|
||||
{
|
||||
case CONFIG_ITEM_NULL: return "null";
|
||||
case CONFIG_ITEM_BOOLEAN: return "boolean";
|
||||
case CONFIG_ITEM_INTEGER: return "integer";
|
||||
case CONFIG_ITEM_STRING: return "string";
|
||||
case CONFIG_ITEM_STRING_ARRAY: return "string array";
|
||||
|
||||
default:
|
||||
hard_assert (!"invalid config item type value");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
config_item_type_is_string (enum config_item_type type)
|
||||
{
|
||||
return type == CONFIG_ITEM_STRING
|
||||
|| type == CONFIG_ITEM_STRING_ARRAY;
|
||||
}
|
||||
|
||||
static void
|
||||
config_item_free (struct config_item_ *self)
|
||||
{
|
||||
switch (self->type)
|
||||
{
|
||||
case CONFIG_ITEM_STRING:
|
||||
|
@ -559,9 +580,32 @@ config_item_destroy (struct config_item_ *self)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
config_item_destroy (struct config_item_ *self)
|
||||
{
|
||||
if (self->schema && self->schema->on_destroy)
|
||||
self->schema->on_destroy (self);
|
||||
|
||||
config_item_free (self);
|
||||
free (self);
|
||||
}
|
||||
|
||||
/// Doesn't do any validations or handle schemas, just moves source data
|
||||
/// to the target item and destroys the source item
|
||||
static void
|
||||
config_item_move (struct config_item_ *self, struct config_item_ *source)
|
||||
{
|
||||
// Not quite sure how to handle that
|
||||
hard_assert (!source->schema);
|
||||
|
||||
config_item_free (self);
|
||||
self->type = source->type;
|
||||
memcpy (&self->value, &source->value, sizeof source->value);
|
||||
free (source);
|
||||
}
|
||||
|
||||
static struct config_item_ *
|
||||
config_item_new (enum config_item_type type)
|
||||
{
|
||||
|
@ -618,19 +662,59 @@ config_item_object (void)
|
|||
return self;
|
||||
}
|
||||
|
||||
/// Doesn't do any validations or such, only moves source data to the item
|
||||
static void
|
||||
config_item_move (struct config_item_ *self, struct config_item_ *source)
|
||||
static bool
|
||||
config_schema_accepts_type
|
||||
(struct config_schema *self, enum config_item_type type)
|
||||
{
|
||||
// TODO
|
||||
if (self->type == type)
|
||||
return true;
|
||||
// This is a bit messy but it has its purpose
|
||||
if (config_item_type_is_string (self->type)
|
||||
&& config_item_type_is_string (type))
|
||||
return true;
|
||||
return self->is_nullable && type == CONFIG_ITEM_NULL;
|
||||
|
||||
}
|
||||
|
||||
static bool
|
||||
config_item_set_from (struct config_item_ *self,
|
||||
struct config_item_ *source, struct error **e)
|
||||
config_item_set_from (struct config_item_ *self, struct config_item_ *source,
|
||||
struct error **e)
|
||||
{
|
||||
hard_assert (self->type == CONFIG_ITEM_OBJECT);
|
||||
// TODO
|
||||
struct config_schema *schema = self->schema;
|
||||
if (!schema)
|
||||
{
|
||||
// Easy, we don't know what this item is
|
||||
config_item_move (self, source);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise we check the type and validate the item
|
||||
if (!config_schema_accepts_type (schema, source->type))
|
||||
{
|
||||
error_set (e, "invalid type of value, expected: %s%s",
|
||||
config_item_type_name (schema->type),
|
||||
schema->is_nullable ? " (or null)" : "");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (schema->validate && !schema->validate (self, source))
|
||||
{
|
||||
// XXX: perhaps "schema->validate" could provide a message for us?
|
||||
error_set (e, "invalid value");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure the string subtype fits the schema
|
||||
if (config_item_type_is_string (self->type)
|
||||
&& config_item_type_is_string (source->type))
|
||||
source->type = self->type;
|
||||
|
||||
config_item_move (self, source);
|
||||
|
||||
// Notify owner about the change so that they can apply it
|
||||
if (schema->on_changed)
|
||||
schema->on_changed (self);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct config_item_ *
|
||||
|
|
Loading…
Reference in New Issue