class T::Enum
def self.enums(&blk)
def self.enums(&blk) raise "enums cannot be defined for T::Enum" if self == T::Enum raise "Enum #{self} was already initialized" if @fully_initialized raise "Enum #{self} is still initializing" if @started_initializing @started_initializing = true @values = T.let(nil, T.nilable(T::Array[T.attached_class])) yield @mapping = T.let(nil, T.nilable(T::Hash[SerializedVal, T.attached_class])) @mapping = {} # Freeze the Enum class and bind the constant names into each of the instances. self.constants(false).each do |const_name| instance = self.const_get(const_name, false) if !instance.is_a?(self) raise "Invalid constant #{self}::#{const_name} on enum. " \ "All constants defined for an enum must be instances itself (e.g. `Foo = new`)." end instance._bind_name(const_name) serialized = instance.serialize if @mapping.include?(serialized) raise "Enum values must have unique serializations. Value '#{serialized}' is repeated on #{self}." end @mapping[serialized] = instance end @values.freeze @mapping.freeze orphaned_instances = T.must(@values) - @mapping.values if !orphaned_instances.empty? raise "Enum values must be assigned to constants: #{orphaned_instances.map {|v| v.instance_variable_get('@serialized_val')}}" end @fully_initialized = true end