Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions lib/compat/opal/lutaml_model_boot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
require "lutaml/model/register"
require "lutaml/model/registrable"
require "lutaml/model/render_policy"
require "lutaml/model/restriction_validation"
require "lutaml/model/runtime_compatibility"
require "lutaml/model/schema"
require "lutaml/model/schema_location"
Expand Down Expand Up @@ -226,6 +227,7 @@
require "lutaml/model/error/collection_true_missing_error"
require "lutaml/model/error/element_count_out_of_range_error"
require "lutaml/model/error/format_adapter_not_specified_error"
require "lutaml/model/error/fraction_digits_error"
require "lutaml/model/error/import_model_with_root_error"
require "lutaml/model/error/incorrect_mapping_argument_error"
require "lutaml/model/error/incorrect_sequence_error"
Expand All @@ -235,12 +237,19 @@
require "lutaml/model/error/invalid_choice_range_error"
require "lutaml/model/error/invalid_format_error"
require "lutaml/model/error/invalid_value_error"
require "lutaml/model/error/length_error"
require "lutaml/model/error/liquid_class_not_found_error"
require "lutaml/model/error/liquid_drop_already_registered_error"
require "lutaml/model/error/liquid_not_enabled_error"
require "lutaml/model/error/mapping_already_exists_error"
require "lutaml/model/error/mapping_attribute_missing_error"
require "lutaml/model/error/mapping_attribute_type_error"
require "lutaml/model/error/max_exclusive_error"
require "lutaml/model/error/max_inclusive_error"
require "lutaml/model/error/max_length_error"
require "lutaml/model/error/min_exclusive_error"
require "lutaml/model/error/min_inclusive_error"
require "lutaml/model/error/min_length_error"
require "lutaml/model/error/mixed_content_collection_error"
require "lutaml/model/error/multiple_mappings_error"
require "lutaml/model/error/no_attributes_defined_liquid_error"
Expand All @@ -251,9 +260,11 @@
require "lutaml/model/error/pattern_not_matched_error"
require "lutaml/model/error/polymorphic_error"
require "lutaml/model/error/required_attribute_missing_error"
require "lutaml/model/error/restriction_error"
require "lutaml/model/error/reverse_transform_block_not_defined_error"
require "lutaml/model/error/reverse_transformation_declaration_error"
require "lutaml/model/error/sorting_configuration_conflict_error"
require "lutaml/model/error/total_digits_error"
require "lutaml/model/error/transform_block_not_defined_error"
require "lutaml/model/error/type_error"
require "lutaml/model/error/type_not_enabled_error"
Expand Down Expand Up @@ -428,8 +439,10 @@
require "lutaml/model/error/register/not_registrable_class_error"
require "lutaml/model/error/type/invalid_value_error"
require "lutaml/model/error/type/max_bound_error"
require "lutaml/model/error/type/max_exclusive_error"
require "lutaml/model/error/type/max_length_error"
require "lutaml/model/error/type/min_bound_error"
require "lutaml/model/error/type/min_exclusive_error"
require "lutaml/model/error/type/min_length_error"
require "lutaml/model/error/type/pattern_not_matched_error"
require "lutaml/model/schema/decorators/attribute"
Expand Down
16 changes: 16 additions & 0 deletions lib/lutaml/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ module Model
autoload :ComparableNil, "#{__dir__}/model/comparable_nil"
autoload :ComparableModel, "#{__dir__}/model/comparable_model"
autoload :CollectionHandler, "#{__dir__}/model/collection_handler"
autoload :RestrictionValidation, "#{__dir__}/model/restriction_validation"
autoload :AttributeValidator, "#{__dir__}/model/attribute_validator"
autoload :Attribute, "#{__dir__}/model/attribute"
autoload :JsonAdapter, "#{__dir__}/model/json_adapter"
Expand Down Expand Up @@ -198,6 +199,21 @@ module Model
"#{__dir__}/model/error/mixed_content_collection_error"
autoload :OrderedContentMappingError,
"#{__dir__}/model/error/ordered_content_mapping_error"
autoload :RestrictionError, "#{__dir__}/model/error/restriction_error"
autoload :MinInclusiveError,
"#{__dir__}/model/error/min_inclusive_error"
autoload :MaxInclusiveError,
"#{__dir__}/model/error/max_inclusive_error"
autoload :MinExclusiveError,
"#{__dir__}/model/error/min_exclusive_error"
autoload :MaxExclusiveError,
"#{__dir__}/model/error/max_exclusive_error"
autoload :MinLengthError, "#{__dir__}/model/error/min_length_error"
autoload :MaxLengthError, "#{__dir__}/model/error/max_length_error"
autoload :LengthError, "#{__dir__}/model/error/length_error"
autoload :TotalDigitsError, "#{__dir__}/model/error/total_digits_error"
autoload :FractionDigitsError,
"#{__dir__}/model/error/fraction_digits_error"

# Error for passing incorrect model type
#
Expand Down
31 changes: 31 additions & 0 deletions lib/lutaml/model/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Attribute

include CollectionHandler
include DeepDupable
include RestrictionValidation

ALLOWED_OPTIONS = %i[
raw
Expand All @@ -29,6 +30,11 @@ class Attribute
ref_key_attribute
xsd_type
union_member_types
min
max
signed
min_length
max_length
].freeze

MODEL_STRINGS = [
Expand Down Expand Up @@ -480,12 +486,15 @@ def validate_value!(value, register, instance_object: nil)

value = cast_value(default_value(register, instance_object), register) if value.nil?
resolved_type = type(register)
validate_restriction_configuration!(resolved_type)

valid_value!(value) &&
valid_collection!(value, self) &&
valid_pattern!(value, resolved_type) &&
validate_polymorphic!(value, resolved_type) &&
execute_validations!(value)

validate_restriction_values!(value, resolved_type)
end

# execute custom validations on the attribute value
Expand Down Expand Up @@ -1020,6 +1029,28 @@ def validate_options!(options)
raise StandardError,
"Invalid option `initialize_empty` given without `collection: true` option"
end

# Length facets are XSD nonNegativeInteger; reject a misconfigured
# type here so a String/Float/nil fails fast instead of raising an
# opaque TypeError later at `value.length >= min`.
%i[min_length max_length].each do |key|
next unless options.key?(key)

value = options[key]
next if value.is_a?(::Integer) && !value.negative?

raise ArgumentError,
"Invalid options for `#{name}`: " \
"`#{key}` must be a non-negative Integer, got #{value.inspect}"
end

# `signed` is true|false per issue #191; a non-boolean (e.g. "false")
# would silently read as signed, so reject it up front.
if options.key?(:signed) && ![true, false].include?(options[:signed])
raise ArgumentError,
"Invalid options for `#{name}`: " \
"`signed` must be true or false, got #{options[:signed].inspect}"
end
true
end

Expand Down
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/fraction_digits_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class FractionDigitsError < RestrictionError
def initialize(attr_name, value, fraction_digits)
@attr_name = attr_name
@value = value
@fraction_digits = fraction_digits

super()
end

def to_s
"#{@attr_name} (#{@value}) exceeds the maximum of " \
"#{@fraction_digits} fraction digits"
end
end
end
end
19 changes: 19 additions & 0 deletions lib/lutaml/model/error/length_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Lutaml
module Model
class LengthError < RestrictionError
def initialize(attr_name, value, length)
@attr_name = attr_name
@value = value
@length = length

super()
end

def to_s
"#{@attr_name} length (#{@value.to_s.length}) must be exactly #{@length}"
end
end
end
end
19 changes: 19 additions & 0 deletions lib/lutaml/model/error/max_exclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Lutaml
module Model
class MaxExclusiveError < RestrictionError
def initialize(attr_name, value, max)
@attr_name = attr_name
@value = value
@max = max

super()
end

def to_s
"#{@attr_name} is `#{@value}`, must be less than #{@max}"
end
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/max_inclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class MaxInclusiveError < RestrictionError
def initialize(attr_name, value, max)
@attr_name = attr_name
@value = value
@max = max

super()
end

def to_s
"#{@attr_name} is `#{@value}`, " \
"must be less than or equal to #{@max}"
end
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/max_length_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class MaxLengthError < RestrictionError
def initialize(attr_name, value, max_length)
@attr_name = attr_name
@value = value
@max_length = max_length

super()
end

def to_s
"#{@attr_name} length (#{@value.to_s.length}) is greater than " \
"the maximum allowed length #{@max_length}"
end
end
end
end
19 changes: 19 additions & 0 deletions lib/lutaml/model/error/min_exclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

module Lutaml
module Model
class MinExclusiveError < RestrictionError
def initialize(attr_name, value, min)
@attr_name = attr_name
@value = value
@min = min

super()
end

def to_s
"#{@attr_name} is `#{@value}`, must be greater than #{@min}"
end
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/min_inclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class MinInclusiveError < RestrictionError
def initialize(attr_name, value, min)
@attr_name = attr_name
@value = value
@min = min

super()
end

def to_s
"#{@attr_name} is `#{@value}`, " \
"must be greater than or equal to #{@min}"
end
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/min_length_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class MinLengthError < RestrictionError
def initialize(attr_name, value, min_length)
@attr_name = attr_name
@value = value
@min_length = min_length

super()
end

def to_s
"#{@attr_name} length (#{@value.to_s.length}) is less than " \
"the minimum required length #{@min_length}"
end
end
end
end
8 changes: 8 additions & 0 deletions lib/lutaml/model/error/restriction_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

module Lutaml
module Model
class RestrictionError < Error
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/total_digits_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
class TotalDigitsError < RestrictionError
def initialize(attr_name, value, total_digits)
@attr_name = attr_name
@value = value
@total_digits = total_digits

super()
end

def to_s
"#{@attr_name} (#{@value}) exceeds the maximum of " \
"#{@total_digits} total digits"
end
end
end
end
2 changes: 2 additions & 0 deletions lib/lutaml/model/error/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ module Type
autoload :InvalidValueError, "#{__dir__}/type/invalid_value_error"
autoload :MinBoundError, "#{__dir__}/type/min_bound_error"
autoload :MaxBoundError, "#{__dir__}/type/max_bound_error"
autoload :MinExclusiveError, "#{__dir__}/type/min_exclusive_error"
autoload :MaxExclusiveError, "#{__dir__}/type/max_exclusive_error"
autoload :PatternNotMatchedError,
"#{__dir__}/type/pattern_not_matched_error"
autoload :MinLengthError, "#{__dir__}/type/min_length_error"
Expand Down
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/type/max_exclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
module Type
class MaxExclusiveError < Error
def initialize(value, max_bound)
@value = value
@max_bound = max_bound

super()
end

def to_s
"Value #{@value} is not less than the exclusive maximum #{@max_bound}"
end
end
end
end
end
20 changes: 20 additions & 0 deletions lib/lutaml/model/error/type/min_exclusive_error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module Lutaml
module Model
module Type
class MinExclusiveError < Error
def initialize(value, min_bound)
@value = value
@min_bound = min_bound

super()
end

def to_s
"Value #{@value} is not greater than the exclusive minimum #{@min_bound}"
end
end
end
end
end
Loading
Loading