Module: Synthra::Mixin
- Defined in:
- lib/synthra/mixin.rb
Overview
Schema Mixin Support
Allows defining reusable field sets that can be included in multiple schemas. More flexible than inheritance for cross-cutting concerns.
Defined Under Namespace
Classes: Registry
Class Method Summary collapse
-
.apply(schema_node, mixin_names) ⇒ AST::SchemaNode
Apply mixins to a schema.
Class Method Details
.apply(schema_node, mixin_names) ⇒ AST::SchemaNode
Apply mixins to a schema
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/synthra/mixin.rb', line 105 def self.apply(schema_node, mixin_names) return schema_node if mixin_names.empty? all_fields = [] all_behaviors = schema_node.behaviors.dup # Add fields from each mixin (in order) mixin_names.each do |mixin_name| mixin = Registry.get(mixin_name) raise Errors::MixinError, "Unknown mixin: #{mixin_name}" unless mixin all_fields.concat(mixin[:fields]) all_behaviors.concat(mixin[:behaviors]) end # Add schema's own fields (override mixin fields if same name) existing_names = all_fields.map { |f| f.respond_to?(:name) ? f.name : f[:name] } schema_node.fields.each do |field| field_name = field.respond_to?(:name) ? field.name : field[:name] if existing_names.include?(field_name) # Replace mixin field with schema field all_fields.reject! { |f| (f.respond_to?(:name) ? f.name : f[:name]) == field_name } end all_fields << field end # Create new schema node with merged fields Parser::AST::SchemaNode.new( name: schema_node.name, fields: all_fields, behaviors: all_behaviors, parent_name: schema_node.parent_name, line: schema_node.line ) end |