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_ *); | 	bool (*validate) (struct config_item_ *, const struct config_item_ *); | ||||||
| 
 | 
 | ||||||
| 	/// The value has changed. Only appliable to objects.
 | 	/// 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"
 | 	/// Free any resources located in "item->user_data"
 | ||||||
| 	void (*on_destroy) (struct config_item_ *item); | 	void (*on_destroy) (struct config_item_ *item); | ||||||
| @ -542,12 +542,33 @@ struct config_schema | |||||||
| 
 | 
 | ||||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||||
| 
 | 
 | ||||||
| static void | static const char * | ||||||
| config_item_destroy (struct config_item_ *self) | config_item_type_name (enum config_item_type type) | ||||||
| { | { | ||||||
| 	if (self->schema && self->schema->on_destroy) | 	switch (type) | ||||||
| 		self->schema->on_destroy (self); | 	{ | ||||||
|  | 	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) | 	switch (self->type) | ||||||
| 	{ | 	{ | ||||||
| 	case CONFIG_ITEM_STRING: | 	case CONFIG_ITEM_STRING: | ||||||
| @ -559,9 +580,32 @@ config_item_destroy (struct config_item_ *self) | |||||||
| 	default: | 	default: | ||||||
| 		break; | 		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); | 	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_ * | static struct config_item_ * | ||||||
| config_item_new (enum config_item_type type) | config_item_new (enum config_item_type type) | ||||||
| { | { | ||||||
| @ -618,19 +662,59 @@ config_item_object (void) | |||||||
| 	return self; | 	return self; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Doesn't do any validations or such, only moves source data to the item
 | static bool | ||||||
| static void | config_schema_accepts_type | ||||||
| config_item_move (struct config_item_ *self, struct config_item_ *source) | 	(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 | static bool | ||||||
| config_item_set_from (struct config_item_ *self, | config_item_set_from (struct config_item_ *self, struct config_item_ *source, | ||||||
| 	struct config_item_ *source, struct error **e) | 	struct error **e) | ||||||
| { | { | ||||||
| 	hard_assert (self->type == CONFIG_ITEM_OBJECT); | 	struct config_schema *schema = self->schema; | ||||||
| 	// TODO
 | 	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_ * | static struct config_item_ * | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user