Module: Literal::OpenAPI::Serializable::ClassMethods
- Defined in:
- lib/literal/openapi/serializable.rb
Constant Summary collapse
- OPENAPI_PROP_KWARGS =
OpenAPI-specific kwargs that ‘prop` should accept. Extracted before forwarding to Literal::Properties#prop.
%i[enum format items_enum].freeze
- OPENAPI_CONSTRAINT_KWARGS =
Schema constraints that map directly to OpenAPI keywords. Stripped from ‘prop` kwargs, stashed on the class, and merged into the property schema at build time.
%i[ minimum maximum exclusive_minimum exclusive_maximum multiple_of min_length max_length pattern min_items max_items unique_items min_properties max_properties const examples ].freeze
Instance Method Summary collapse
- #__literal_property_class__ ⇒ Object
-
#__openapi_constraints__ ⇒ Object
Per-class map of property-name → extra schema constraints (minimum, maximum, pattern, etc.).
-
#__openapi_optional__ ⇒ Object
Per-class set of property names declared with ‘optional: true`.
-
#__openapi_required__ ⇒ Object
Per-class set of property names that should appear in ‘required`.
-
#openapi_additional_properties(value) ⇒ Object
Opt out of ‘additionalProperties: false` for this class.
- #openapi_additional_properties_value ⇒ Object
-
#openapi_description(value = nil) ⇒ Object
Schema-level description for the class.
- #openapi_schema(adapter: Literal::OpenAPI["3.0"]) ⇒ Object
-
#prop(name, type, kind = :keyword, **kwargs, &coercion) ⇒ Object
Override Literal::Properties#prop to accept OpenAPI-specific kwargs (enum, format, items_enum, optional, schema constraints).
Instance Method Details
#__literal_property_class__ ⇒ Object
52 53 54 |
# File 'lib/literal/openapi/serializable.rb', line 52 def __literal_property_class__ Literal::OpenAPI::Property end |
#__openapi_constraints__ ⇒ Object
Per-class map of property-name → extra schema constraints (minimum, maximum, pattern, etc.). Populated by ‘prop` when constraint kwargs are passed, and merged into the property schema at build time.
73 74 75 |
# File 'lib/literal/openapi/serializable.rb', line 73 def __openapi_constraints__ @__openapi_constraints__ ||= {} end |
#__openapi_optional__ ⇒ Object
Per-class set of property names declared with ‘optional: true`. These are omitted from the emitted `required` list regardless of runtime nilability or defaults.
66 67 68 |
# File 'lib/literal/openapi/serializable.rb', line 66 def __openapi_optional__ @__openapi_optional__ ||= ::Set.new end |
#__openapi_required__ ⇒ Object
Per-class set of property names that should appear in ‘required`. Populated automatically by `prop` unless `optional: true` was passed —every declared prop is required by default.
59 60 61 |
# File 'lib/literal/openapi/serializable.rb', line 59 def __openapi_required__ @__openapi_required__ ||= ::Set.new end |
#openapi_additional_properties(value) ⇒ Object
Opt out of ‘additionalProperties: false` for this class. NOT inherited — each class explicitly sets it.
86 87 88 |
# File 'lib/literal/openapi/serializable.rb', line 86 def openapi_additional_properties(value) @openapi_additional_properties = value end |
#openapi_additional_properties_value ⇒ Object
90 91 92 93 94 |
# File 'lib/literal/openapi/serializable.rb', line 90 def openapi_additional_properties_value return @openapi_additional_properties if instance_variable_defined?(:@openapi_additional_properties) false end |
#openapi_description(value = nil) ⇒ Object
Schema-level description for the class. Emitted at the top level of the generated object schema. Call with no args to read.
79 80 81 82 |
# File 'lib/literal/openapi/serializable.rb', line 79 def openapi_description(value = nil) @openapi_description = value unless value.nil? @openapi_description if instance_variable_defined?(:@openapi_description) end |
#openapi_schema(adapter: Literal::OpenAPI["3.0"]) ⇒ Object
96 97 98 99 |
# File 'lib/literal/openapi/serializable.rb', line 96 def openapi_schema(adapter: Literal::OpenAPI["3.0"]) instance = adapter.is_a?(Class) ? adapter.new : adapter instance.build_schema(self) end |
#prop(name, type, kind = :keyword, **kwargs, &coercion) ⇒ Object
Override Literal::Properties#prop to accept OpenAPI-specific kwargs (enum, format, items_enum, optional, schema constraints). Strips those kwargs, forwards the rest to super (which creates a Literal::OpenAPI::Property via literal_property_class), then tags the created property with the OpenAPI extras and registers the name in the required/optional/constraints sets. rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
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 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/literal/openapi/serializable.rb', line 108 def prop(name, type, kind = :keyword, **kwargs, &coercion) optional = kwargs.delete(:optional) enum = kwargs.delete(:enum) format = kwargs.delete(:format) items_enum = kwargs.delete(:items_enum) constraints = OPENAPI_CONSTRAINT_KWARGS.each_with_object({}) do |k, h| h[k] = kwargs.delete(k) if kwargs.key?(k) end effective_type = if enum enum_values = enum.freeze predicate = Literal::Types::PredicateType.new( message: "enum(#{enum_values.inspect})", block: ->(v) { enum_values.include?(v) } ) # When the declared type is nilable, apply the enum predicate only # to the non-nil inner type so that nil stays acceptable. Otherwise # `_Nilable(String) & enum(...)` would reject nil (predicate fails # because nil isn't in the enum), which contradicts the nilability. if type.is_a?(Literal::Types::NilableType) Literal::Types::NilableType.new( Literal::Types::IntersectionType.new([type.type, predicate]) ) else Literal::Types::IntersectionType.new([type, predicate]) end else type end super(name, effective_type, kind, **kwargs, &coercion) property = literal_properties[name] property.instance_variable_set(:@enum, enum) if enum property.instance_variable_set(:@format, format) if format property.instance_variable_set(:@items_enum, items_enum) if items_enum if optional __openapi_optional__ << name else __openapi_required__ << name end __openapi_constraints__[name] = constraints if constraints.any? name end |