Skip to content

Commit

Permalink
Merge pull request #19 from ismasan/shorthand_array_attribute
Browse files Browse the repository at this point in the history
Shorthand array attribute
  • Loading branch information
ismasan authored Sep 1, 2024
2 parents 7f2ffc2 + 7c269d6 commit 368bb4f
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,25 @@ Note that this does NOT work with union'd or piped structs.
attribute :company, Company | Person do
```

#### Shorthand array syntax

```ruby
attribute :things, [] # Same as attribute :things, Types::Array
attribute :numbers, [Integer] # Same as attribute :numbers, Types::Array[Integer]
attribute :people, [Person] # same as attribute :people, Types::Array[Person]
attribute :friends, [Person] do # same as attribute :friends, Types::Array[Person] do...
attribute :phone_number, Integer
end
```

Note that, if you want to match an attribute value against a literal array, you need to use `#value`

```ruby
attribute :one_two_three, Types::Array.value[[1, 2, 3]])
```

#### Optional Attributes

Using `attribute?` allows for optional attributes. If the attribute is not present, these attribute values will be `nil`

```ruby
Expand Down
3 changes: 3 additions & 0 deletions lib/plumb/attributes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,15 @@ def node_name = :data
# attribute(:name, String)
# attribute(:friends, Types::Array) { attribute(:name, String) }
# attribute(:friends, Types::Array) # same as Types::Array[Types::Any]
# attribute(:friends, []) # same as Types::Array[Types::Any]
# attribute(:friends, Types::Array[Person])
# attribute(:friends, [Person])
#
def attribute(name, type = Types::Any, &block)
key = Key.wrap(name)
name = key.to_sym
type = Composable.wrap(type)

if block_given? # :foo, Array[Data] or :foo, Struct
type = __plumb_struct_class__ if type == Types::Any
type = Plumb.decorate(type) do |node|
Expand Down
26 changes: 26 additions & 0 deletions spec/data_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,32 @@ class DifferentClass
expect(office.staff.first.errors[:age]).not_to be_empty
end

specify 'shorthand typed array syntax' do
klass = Class.new(Types::Data) do
attribute :typed_array, [Integer]
attribute :untyped_array, []
attribute :data_array, [] do
attribute :name, String
end
end

thing = klass.new(typed_array: [1, 2, 3], untyped_array: [1, 'hello'], data_array: [{ name: 'foo' }])
expect(thing.typed_array).to eq([1, 2, 3])
expect(thing.untyped_array).to eq([1, 'hello'])
expect(thing.data_array.map(&:name)).to eq(['foo'])
expect(thing.valid?).to be(true)
thing = klass.new(typed_array: [1, 2, '3'])
expect(thing.valid?).to be(false)
end

specify 'invalid shorthard array with multiple elements' do
expect do
klass = Class.new(Types::Data) do
attribute :typed_array, [Integer, String]
end
end.to raise_error(ArgumentError)
end

specify 'invalid' do
user = Types::User.new(
name: 'Jane',
Expand Down

0 comments on commit 368bb4f

Please sign in to comment.