Module: Rbdantic::JsonSchema::Types

Defined in:
lib/rbdantic/json_schema/types.rb

Overview

Type-to-schema mappings

Class Method Summary collapse

Class Method Details

.add_array_constraints(schema, constraints, defs_registry: nil, by_alias: false) ⇒ Object



86
87
88
89
90
91
92
93
94
# File 'lib/rbdantic/json_schema/types.rb', line 86

def self.add_array_constraints(schema, constraints, defs_registry: nil, by_alias: false)
  schema["minItems"] = constraints[:min_items] if constraints[:min_items]
  schema["maxItems"] = constraints[:max_items] if constraints[:max_items]
  schema["uniqueItems"] = constraints[:unique_items] if constraints[:unique_items]
  if constraints[:element_type]
    schema["items"] =
      to_schema(constraints[:element_type], defs_registry: defs_registry, by_alias: by_alias)
  end
end

.add_hash_constraints(schema, constraints) ⇒ Object



96
97
98
99
# File 'lib/rbdantic/json_schema/types.rb', line 96

def self.add_hash_constraints(schema, constraints)
  schema["minProperties"] = constraints[:min_properties] if constraints[:min_properties]
  schema["maxProperties"] = constraints[:max_properties] if constraints[:max_properties]
end

.add_numeric_constraints(schema, constraints) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/rbdantic/json_schema/types.rb', line 78

def self.add_numeric_constraints(schema, constraints)
  schema["minimum"] = constraints[:ge] if constraints[:ge]
  schema["exclusiveMinimum"] = constraints[:gt] if constraints[:gt]
  schema["maximum"] = constraints[:le] if constraints[:le]
  schema["exclusiveMaximum"] = constraints[:lt] if constraints[:lt]
  schema["multipleOf"] = constraints[:multiple_of] if constraints[:multiple_of]
end

.add_string_constraints(schema, constraints) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rbdantic/json_schema/types.rb', line 63

def self.add_string_constraints(schema, constraints)
  schema["minLength"] = constraints[:min_length] if constraints[:min_length]
  schema["maxLength"] = constraints[:max_length] if constraints[:max_length]
  schema["pattern"] = constraints[:pattern].source if constraints[:pattern]

  if constraints[:format]
    format_map = {
      email: "email",
      uri: "uri",
      uuid: "uuid"
    }
    schema["format"] = format_map[constraints[:format]] if format_map[constraints[:format]]
  end
end

.base_schema(type, defs_registry: nil, by_alias: false) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/rbdantic/json_schema/types.rb', line 28

def self.base_schema(type, defs_registry: nil, by_alias: false)
  # Use direct class comparison (type == Class), not === (which checks instance type)
  if type == ::String
    { "type" => "string" }
  elsif type == ::Integer
    { "type" => "integer" }
  elsif type == ::Float
    { "type" => "number" }
  elsif type == ::Time
    { "type" => "string", "format" => "date-time" }
  elsif type == ::Date
    { "type" => "string", "format" => "date" }
  elsif type == ::DateTime
    { "type" => "string", "format" => "date-time" }
  elsif type == ::Rbdantic::Boolean
    { "type" => "boolean" }
  elsif type == ::Array
    { "type" => "array" }
  elsif type == ::Hash
    { "type" => "object" }
  elsif type.is_a?(Class) && type < ::Rbdantic::BaseModel
    if defs_registry
      unless defs_registry.registered?(type) || defs_registry.being_processed?(type)
        Generator.generate(type, top_level: false, defs_registry: defs_registry, by_alias: by_alias)
      end

      defs_registry.ref_for(type)
    else
      Generator.generate(type, top_level: false, defs_registry: nil, by_alias: by_alias)
    end
  else
    { "type" => "object" }
  end
end

.to_schema(type, **constraints) ⇒ Hash

Map Ruby type to JSON Schema type



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/rbdantic/json_schema/types.rb', line 12

def self.to_schema(type, **constraints)
  defs_registry = constraints[:defs_registry]
  by_alias = constraints[:by_alias]
  constraints = constraints.reject { |k, _| k == :defs_registry || k == :by_alias }

  schema = base_schema(type, defs_registry: defs_registry, by_alias: by_alias)

  # Add constraints
  add_string_constraints(schema, constraints) if type == ::String
  add_numeric_constraints(schema, constraints) if type == ::Integer || type == ::Float
  add_array_constraints(schema, constraints, defs_registry: defs_registry, by_alias: by_alias) if type == ::Array
  add_hash_constraints(schema, constraints) if type == ::Hash

  schema
end