Last active
January 25, 2025 15:40
-
-
Save fsubal/b53d00b6c74e5951c8c09c8f8c74dc5c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module AttrReaderGuard | |
extend ActiveSupport::Concern | |
class InvalidError < ArgumentError | |
PREFIX = '[attr_reader_guard!]:' | |
def initialize(subject, predicate) | |
super [PREFIX, subject, predicate].join(' ') | |
end | |
end | |
included do | |
cattr_reader :attr_reader_guards, default: ->{ {} } | |
end | |
class_methods do | |
def attr_reader_guard!(name, &matcher) | |
unless block_given? | |
raise InvalidError, name, 'has no matcher.' | |
end | |
@attr_reader_guards ||= {} | |
@attr_reader_guards[name.to_sym] = matcher | |
attr_reader name.to_sym | |
end | |
end | |
def initialize(**attributes) | |
super(**attributes) | |
attributes.each do |name, value| | |
matcher = attr_reader_guards.fetch(name.to_sym) | |
unless matcher.call(value) | |
raise InvalidError, name, 'does not satisfy the pattern' | |
end | |
instance_variable_set("@#{name}", value) | |
rescue KeyError | |
raise InvalidError, name, "is not accepted for #{self.class} (unknown attribute)" | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ResizeImages | |
include AttrReaderGuard | |
attr_reader_guard!(:width) { it in Integer | /^\d+$/ } | |
attr_reader_guard!(:height) { it in Integer | /^\d+$/ } | |
attr_reader_guard!(:input_images) { it in [String, String, String] } | |
attr_reader_guard!(:object_fit) { it in 'cover' | 'contain' } | |
def width = super.to_i | |
def height = super.to_i | |
def header_image = input_images.first | |
def body_image = input_images.second | |
def footer_image = input_images.third | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment