Class: Meta::JsonSchema::BaseSchema

Inherits:
Object
  • Object
show all
Defined in:
lib/meta/json_schema/schemas/base_schema.rb

Overview

表示一个基本类型的 Schema,或继承自该类表示一个拥有其他扩展能力的 Schema.

该类包含了通用 JsonSchema 思维的基本逻辑,比如 stage 和 scope. 其他 Schema 类应当主动地继 承自该类,这样就会自动获得 stage 和 scope 的能力。

该类剩余的逻辑是提供一个 ‘options` 属性,用于描述该 Schema. 因此,直接实例化该类可以用于表示 基本类型,而继承该类可以用于表示还有内部递归处理的对象和数组类型。这时,应当在子类的构造函数中调 用父类的构造方法,以便初始化 `options` 属性。并且在子类中重写 `filter_internal` 方法,实现 内部递归处理的逻辑。这种模式的案例主要是 `ObjectSchema` 和 `ArraySchema`.

如果是组合模式,也应当继承自该类,以便获得 stage 和 scope 的能力。但是,组合模式的 ‘options` 调用是非法的,因此不应当在构造函数中调用父类的构造方法。此时 options 为 nil,这样用到 options 的地方都会抛出异常(NoMethodError: undefined method `[]’ for nil:NilClass)。这种模式 的案例很多,包括 StagingSchema、RefSchema 等。

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ BaseSchema

Returns a new instance of BaseSchema.

Raises:

  • (ArgumentError)


31
32
33
34
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 31

def initialize(options = {})
  raise ArgumentError, 'options 必须是 Hash 类型' unless options.is_a?(Hash)
  @options = SchemaOptions::BaseBuildOptions.check(options)
end

Instance Attribute Details

#optionsObject (readonly)

‘options` 包含了转换器、验证器、文档、选项。

由于本对象可继承,基于不同的继承可分别表示基本类型、对象和数组,所以该属 性可用在不同类型的对象上。需要时刻留意的是,无论是用在哪种类型的对象内, ‘options` 属性都是描述该对象的本身,而不是深层的属性。

较常出现错误的是数组,‘options` 是描述数组的,而不是描述数组内部元素的。



29
30
31
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 29

def options
  @options
end

Instance Method Details

#defined_scopes(stage:, defined_scopes_mapping:) ⇒ Object

defined_scopes_mapping 是一个 Hash,用于缓存已经计算出的 scopes,用于避免重复计算。其主要针对的是具有命名系统的 Schema,如 Meta::Entity



87
88
89
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 87

def defined_scopes(stage:, defined_scopes_mapping:)
  []
end

#filter(value, user_options = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 40

def filter(value, user_options = {})
  user_options = SchemaOptions::UserOptions::Filter.check(user_options)

  value = value_callback(user_options) if options[:value]
  value = before_callback(value, user_options) if options[:before]
  value = JsonSchema::Presenters.present(options[:presenter], value) if options[:presenter]
  value = resolve_default_value(options[:default]) if value.nil? && options.key?(:default)
  value = options[:convert].call(value) if options[:convert]

  # 第一步,转化值。
  # 需要注意的是,对象也可能被转换,因为并没有深层次的结构被声明。
  type = options[:type]
  unless user_options[:type_conversion] == false || type.nil? || value.nil?
    begin
      value = JsonSchema::TypeConverter.convert_value(value, type)
    rescue JsonSchema::TypeConvertError => e
      raise JsonSchema::ValidationError.new(e.message)
    end
  end

  # 第二步,做校验。
  validate!(value, options) unless user_options[:validation] == false

  # 第三步,如果存在内部属性,递归调用。
  value = filter_internal(value, user_options) unless value.nil?

  # 最后,返回 value
  value = after_callback(value, user_options) if options[:after]
  value
end

#filter?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 36

def filter?
  true
end

#find_schema(stage:, scope:) ⇒ Object

返回能够处理 scope 和 stage 的 schema(可以是 self),否则应返回 UnsupportedStageSchema 或 nil.



72
73
74
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 72

def find_schema(stage:, scope:)
  staged(stage)&.scoped(scope)
end

#if?(object_value, execution = nil) ⇒ Boolean

执行 if: 选项,返回 true 或 false

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 92

def if?(object_value, execution = nil)
  if_block = options[:if]
  return true if if_block.nil?

  args_length = if_block.lambda? ? if_block.arity : 1
  args = args_length > 0 ? [object_value] : []
  if execution
    execution.instance_exec(*args, &options[:if])
  else
    options[:if]&.call(*args)
  end
end

#scoped(scope) ⇒ Object

返回能够处理 scope 的 schema(可以是 self),否则返回 nil.



82
83
84
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 82

def scoped(scope)
  self
end

#staged(stage) ⇒ Object

返回能够处理 stage 的 schema(可以是 self),否则返回 UnsupportedStageSchema.



77
78
79
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 77

def staged(stage)
  self
end

#to_schemaObject



127
128
129
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 127

def to_schema
  self
end

#to_schema_doc(**user_options) ⇒ Object

生成 Swagger 文档的 schema 格式。

选项:

  • stage: 传递 :param 或 :render

  • schema_docs_mapping: 用于保存已经生成的 Schema

  • defined_scopes_mapping: 用于缓存已经定义的 scopes

  • presenter: 兼容 Grape 框架的实体类



116
117
118
119
120
121
122
123
124
125
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 116

def to_schema_doc(**user_options)
  return Presenters.to_schema_doc(options[:presenter], options) if options[:presenter]

  schema = {}
  schema[:type] = options[:type] if options[:type]
  schema[:description] = options[:description] if options[:description]
  schema[:enum] = options[:enum] if options[:enum]

  schema
end

#value?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/meta/json_schema/schemas/base_schema.rb', line 105

def value?
  options[:value] != nil
end