Class: Respect::Schema
- Inherits:
-
Object
- Object
- Respect::Schema
- Includes:
- DocHelper
- Defined in:
- lib/respect/schema.rb
Overview
Base class for all object schema.
A schema defines the expected structure and format for a given object. It is similar in spirit to json-schemajson-schema.org(json-schema.org/) specification but uses Ruby DSL as definition. Using the DSL is not mandatory since you can also defines a schema using its own methods.
Almost all Schema sub-classes has an associated statement available in the DSL for defining it. This statement is named after the class name (see Schema.statement_name). However all sub-classes do not have a statement associated (see schema_for).
You can define such a schema using the Schema.define method. The #validate method allow you to check whether the given object is valid according to this schema. Various options can be passed to the schema when initializing it.
While validating an object the schema build a sanitized version of this object including all the validated part. The value presents in this sanitized object have generally a type specific to the contents they represents. For instance, a URI would be represented as a string in the original object but as a URI object in the sanitized object. There is a she-bang version of the validation method which update the value of the given object in-place with the value from the sanitized object if the validation succeeded.
You can pass several options when creating a Schema:
required |
whether this property associated to this schema is required in the hash schema (true by default). |
default |
the default value to use for the associated property if it is not present. Setting a default value make the property optional. (nil by default) |
doc |
the documentation of this schema (nil by default). A documentation is composed of a title followed by an empty line and an optional long description. If set to false, then this schema is considered as an implementation details that should not be publicly documented. Thus, it will not be dumped as json-schema.org. |
allow_nil |
whether the schema accept nil as validation value. (false by default). This option is not supported yet by the json-schema.org standard. |
These options applies to all schema sub-classes.
In addition to these options, you can configure any defined Validator. Validators are run during validation process by certain schema class like IntegerSchema, StringSchema, etc... They are mostly non-containers schema. In the following code the GreaterThanValidator will be run at validation time with the value o:
IntegerSchema.define greater_than: 0
This class is abstract. You cannot instantiate it directly. Use one of its sub-classes instead.
Direct Known Subclasses
AnySchema, ArraySchema, BooleanSchema, CompositeSchema, HashSchema, NullSchema, NumericSchema, StringSchema
Instance Attribute Summary (collapse)
-
- (Object) last_error
readonly
Return the last validation error that happens during the validation process.
-
- (Object) options
readonly
Returns the hash of options.
-
- (Object) sanitized_object
readonly
Returns the sanitized object.
Class Method Summary (collapse)
-
+ (Object) def_class
Return the definition class symbol for this schema class or nil if there is no class (see Schema.def_class_name).
-
+ (Object) def_class_name
Return the associated def class name for this class.
-
+ (Object) default_options
Return the default options for this schema class.
-
+ (Object) define(*args, &block)
If a corresponding def class exists for this class (see Schema.def_class) it defines a new schema by evaluating the given block in the context of this definition class.
-
+ (Object) statement_name
Build a statement name from this class name.
Instance Method Summary (collapse)
-
- (Object) ==(other)
Two schema are equal if they have the same type and the set of options.
-
- (Boolean) allow_nil?
Returns whether this schema accept nil as validation value.
-
- (Object) default
Returns the default value used when this schema is missing.
-
- (Object) documentation
(also: #doc)
Returns the documentation of this schema.
-
- (Boolean) documented?
Returns whether this schema must be documented (i.e. not ignored when dumped).
-
- (Boolean) has_default?
Returns whether this schema has a default value defined.
-
- (Schema) initialize(options = {})
constructor
Create a new schema using the given options.
- - (Object) initialize_copy(other)
-
- (Object) inspect
Returns a string containing a human-readable representation of this schema.
-
- (Object) non_default_options
Return the options with no default value.
-
- (Boolean) optional?
Whether this schema is optional.
-
- (Boolean) required?
Whether this schema is required.
-
- (Object) sanitize!(object)
Sanitize the given object in-place if it validates this schema.
-
- (Object) sanitize_object!(object)
A shortcut for sanitize_object!.
-
- (Object) to_h(format = :org3)
Convert this schema to a hash representation following the given format.
-
- (Object) to_json(format = :org3)
Serialize this schema to a JSON string following the given format.
-
- (Object) to_s
Returns a string containing ruby code defining this schema.
-
- (Object) validate(object)
Raise a ValidationError if the given object is not validated by this schema.
-
- (Object) validate!(object)
Return true or false whether this schema validates the given object.
-
- (Boolean) validate?(object)
Return whether the given object validates this schema.
Methods included from DocHelper
Constructor Details
- (Schema) initialize(options = {})
Create a new schema using the given options.
127 128 129 130 |
# File 'lib/respect/schema.rb', line 127 def initialize( = {}) @sanitized_object = nil @options = self.class..merge() end |
Instance Attribute Details
- (Object) last_error (readonly)
Return the last validation error that happens during the validation process. (set by #validate?). Reset each time #validate? is called.
197 198 199 |
# File 'lib/respect/schema.rb', line 197 def last_error @last_error end |
- (Object) options (readonly)
Returns the hash of options.
142 143 144 |
# File 'lib/respect/schema.rb', line 142 def @options end |
- (Object) sanitized_object
Returns the sanitized object. It is nil as long as you have not validated any object. It is overwritten every times you call #validate. If the validation failed it will be reset to nil.
139 140 141 |
# File 'lib/respect/schema.rb', line 139 def sanitized_object @sanitized_object end |
Class Method Details
+ (Object) def_class
Return the definition class symbol for this schema class or nil if there is no class (see def_class_name)
99 100 101 |
# File 'lib/respect/schema.rb', line 99 def def_class self.def_class_name.safe_constantize end |
+ (Object) def_class_name
Return the associated def class name for this class. Example:
ArraySchema.def_class_name #=> "ArrayDef"
HashSchema.def_class_name #=> "HashDef"
Schema.def_class_name #=> "SchemaDef"
89 90 91 92 93 94 95 |
# File 'lib/respect/schema.rb', line 89 def def_class_name if self == Schema "Respect::SchemaDef" else self.name.sub(/Schema$/, 'Def') end end |
+ (Object) default_options
Return the default options for this schema class. If you override this method in sub-classes, call super and merge the result with your default options.
115 116 117 118 119 120 121 122 |
# File 'lib/respect/schema.rb', line 115 def { required: true, default: nil, doc: nil, allow_nil: false, }.freeze end |
+ (Object) define(*args, &block)
If a corresponding def class exists for this class (see def_class) it defines a new schema by evaluating the given block in the context of this definition class. It behaves as an alias for new if no block is given.
If there is no associated def class the block is passed to the constructor.
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/respect/schema.rb', line 71 def define(*args, &block) def_class = self.def_class if def_class if block def_class.eval(*args, &block) else self.new(*args) end else self.new(*args, &block) end end |
+ (Object) statement_name
Build a statement name from this class name.
Example:
Schema.statement_name #=> "schema"
HashSchema.statement_name #=> "hash"
108 109 110 |
# File 'lib/respect/schema.rb', line 108 def statement_name self.name.underscore.sub(/^.*\//, '').sub(/_schema$/, '') end |
Instance Method Details
- (Object) ==(other)
Two schema are equal if they have the same type and the set of options. Sub-class definition may include more attributes.
275 276 277 |
# File 'lib/respect/schema.rb', line 275 def ==(other) self.class == other.class && @options == other. end |
- (Boolean) allow_nil?
Returns whether this schema accept nil as validation value.
178 179 180 |
# File 'lib/respect/schema.rb', line 178 def allow_nil? !!@options[:allow_nil] end |
- (Object) default
Returns the default value used when this schema is missing.
168 169 170 |
# File 'lib/respect/schema.rb', line 168 def default @options[:default] end |
- (Object) documentation Also known as: doc
Returns the documentation of this schema.
145 146 147 |
# File 'lib/respect/schema.rb', line 145 def documentation @options[:doc] end |
- (Boolean) documented?
Returns whether this schema must be documented (i.e. not ignored when dumped).
153 154 155 |
# File 'lib/respect/schema.rb', line 153 def documented? @options[:doc] != false end |
- (Boolean) has_default?
Returns whether this schema has a default value defined.
173 174 175 |
# File 'lib/respect/schema.rb', line 173 def has_default? @options[:default] != nil end |
- (Object) initialize_copy(other)
132 133 134 |
# File 'lib/respect/schema.rb', line 132 def initialize_copy(other) @options = other..dup end |
- (Object) inspect
Returns a string containing a human-readable representation of this schema.
232 233 234 235 236 237 238 |
# File 'lib/respect/schema.rb', line 232 def inspect "#<%s:0x%x %s>" % [ self.class.name, self.object_id, instance_variables.map{|v| "#{v}=#{instance_variable_get(v).inspect}" }.join(", ") ] end |
- (Object) non_default_options
Return the options with no default value. (Useful when writing a dumper)
258 259 260 |
# File 'lib/respect/schema.rb', line 258 def @options.select{|opt, value| value != self.class.[opt] } end |
- (Boolean) optional?
Whether this schema is optional.
163 164 165 |
# File 'lib/respect/schema.rb', line 163 def optional? !required? end |
- (Boolean) required?
Whether this schema is required. (opposite of optional?)
158 159 160 |
# File 'lib/respect/schema.rb', line 158 def required? @options[:required] && !has_default? end |
- (Object) sanitize!(object)
Sanitize the given object in-place if it validates this schema. The sanitized object is returned. ValidationError is raised on error.
221 222 223 224 |
# File 'lib/respect/schema.rb', line 221 def sanitize!(object) validate(object) sanitize_object!(object) end |
- (Object) sanitize_object!(object)
A shortcut for Respect.sanitize_object!.
227 228 229 |
# File 'lib/respect/schema.rb', line 227 def sanitize_object!(object) Respect.sanitize_object!(object, self.sanitized_object) end |
- (Object) to_h(format = :org3)
Convert this schema to a hash representation following the given format.
264 265 266 267 268 269 270 271 |
# File 'lib/respect/schema.rb', line 264 def to_h(format = :org3) case format when :org3 Org3Dumper.new(self).dump else raise ArgumentError, "unknown format '#{format}'" end end |
- (Object) to_json(format = :org3)
Serialize this schema to a JSON string following the given format.
247 248 249 250 251 252 253 254 |
# File 'lib/respect/schema.rb', line 247 def to_json(format = :org3) case format when :org3 self.to_h(:org3).to_json else raise ArgumentError, "unknown format '#{format}'" end end |
- (Object) to_s
Returns a string containing ruby code defining this schema. Theoretically, you can evaluate it and get the same schema afterward.
242 243 244 |
# File 'lib/respect/schema.rb', line 242 def to_s DslDumper.new(self).dump end |
- (Object) validate(object)
Raise a ValidationError if the given object is not validated by this schema. Returns true otherwise. A sanitized version of the object is built during this process and you can access it via #sanitized_object. Rewrite it in sub-classes.
203 204 205 |
# File 'lib/respect/schema.rb', line 203 def validate(object) raise NoMethodError, "override me in sub-classes" end |
- (Object) validate!(object)
Return true or false whether this schema validates the given object. If it does object is updated in-place with the sanitized value. This method does not raise a ValidationError. You can access the error using #last_error.
211 212 213 214 215 216 217 |
# File 'lib/respect/schema.rb', line 211 def validate!(object) valid = validate?(object) if valid sanitize_object!(object) end valid end |
- (Boolean) validate?(object)
Return whether the given object validates this schema. You can get the validation error via #last_error.
184 185 186 187 188 189 190 191 192 |
# File 'lib/respect/schema.rb', line 184 def validate?(object) begin validate(object) true rescue ValidationError => e @last_error = e false end end |