Module: EasyTalk::TypeIntrospection
- Extended by:
- T::Sig
- Defined in:
- lib/easy_talk/type_introspection.rb
Overview
Centralized module for robust type introspection.
This module provides predicate methods for detecting types without relying on brittle string-based checks. It uses Sorbet's type system properly and handles edge cases gracefully.
Constant Summary collapse
- PRIMITIVE_TO_JSON_SCHEMA =
Mapping of Ruby classes to JSON Schema types
{ String => 'string', Integer => 'integer', Float => 'number', BigDecimal => 'number', TrueClass => 'boolean', FalseClass => 'boolean', NilClass => 'null' }.freeze
Class Method Summary collapse
- .array_type?(type) ⇒ Boolean
- .boolean_type?(type) ⇒ Boolean
- .boolean_union_type?(type_class) ⇒ Boolean
- .extract_inner_type(type) ⇒ Object
- .get_type_class(type) ⇒ Object
- .json_schema_type(type) ⇒ Object
- .nilable_type?(type) ⇒ Boolean
- .primitive_type?(type) ⇒ Boolean
- .typed_array?(type) ⇒ Boolean
Class Method Details
.array_type?(type) ⇒ Boolean
108 109 110 111 112 |
# File 'lib/easy_talk/type_introspection.rb', line 108 def array_type?(type) return false if type.nil? type == Array || type.is_a?(T::Types::TypedArray) || type.is_a?(EasyTalk::Types::Tuple) end |
.boolean_type?(type) ⇒ Boolean
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/easy_talk/type_introspection.rb', line 48 def boolean_type?(type) return false if type.nil? return true if [TrueClass, FalseClass].include?(type) return true if type.respond_to?(:raw_type) && [TrueClass, FalseClass].include?(type.raw_type) # Check for T::Boolean which is a TypeAlias with name 'T::Boolean' return true if type.respond_to?(:name) && type.name == 'T::Boolean' # Check for union types containing TrueClass and FalseClass if type.respond_to?(:types) type_classes = type.types.map { |t| t.respond_to?(:raw_type) ? t.raw_type : t } return type_classes.sort_by(&:name) == [FalseClass, TrueClass].sort_by(&:name) end false end |
.boolean_union_type?(type_class) ⇒ Boolean
78 79 80 |
# File 'lib/easy_talk/type_introspection.rb', line 78 def boolean_union_type?(type_class) type_class.is_a?(Array) && type_class.sort_by(&:name) == [FalseClass, TrueClass].sort_by(&:name) end |
.extract_inner_type(type) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/easy_talk/type_introspection.rb', line 202 def extract_inner_type(type) return type if type.nil? if type.respond_to?(:unwrap_nilable) unwrapped = type.unwrap_nilable return unwrapped.respond_to?(:raw_type) ? unwrapped.raw_type : unwrapped end if type.respond_to?(:types) non_nil = type.types.find do |t| raw = t.respond_to?(:raw_type) ? t.raw_type : t raw != NilClass end return non_nil.respond_to?(:raw_type) ? non_nil.raw_type : non_nil if non_nil end type end |
.get_type_class(type) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/easy_talk/type_introspection.rb', line 179 def get_type_class(type) return nil if type.nil? return type if type.is_a?(Class) return type.raw_type if type.respond_to?(:raw_type) return Array if type.is_a?(T::Types::TypedArray) || type.is_a?(EasyTalk::Types::Tuple) return [TrueClass, FalseClass] if boolean_type?(type) if nilable_type?(type) inner = extract_inner_type(type) return get_type_class(inner) if inner && inner != type end nil end |
.json_schema_type(type) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/easy_talk/type_introspection.rb', line 156 def json_schema_type(type) return 'object' if type.nil? return 'boolean' if boolean_type?(type) resolved_class = if type.is_a?(Class) type elsif type.respond_to?(:raw_type) type.raw_type end PRIMITIVE_TO_JSON_SCHEMA[resolved_class] || resolved_class&.name&.downcase || 'object' end |
.nilable_type?(type) ⇒ Boolean
123 124 125 126 127 |
# File 'lib/easy_talk/type_introspection.rb', line 123 def nilable_type?(type) return false if type.nil? type.respond_to?(:nilable?) && type.nilable? end |
.primitive_type?(type) ⇒ Boolean
134 135 136 137 138 139 140 141 142 143 |
# File 'lib/easy_talk/type_introspection.rb', line 134 def primitive_type?(type) return false if type.nil? resolved = if type.is_a?(Class) type elsif type.respond_to?(:raw_type) type.raw_type end PRIMITIVE_TO_JSON_SCHEMA.key?(resolved) end |
.typed_array?(type) ⇒ Boolean
91 92 93 94 95 |
# File 'lib/easy_talk/type_introspection.rb', line 91 def typed_array?(type) return false if type.nil? type.is_a?(T::Types::TypedArray) end |