tapioca-compilers-dry_struct
This script is a Tapioca's custom DSL compiler for dry-struct.
From this ruby code,
class Example < Dry::Struct
attribute :attr01, Types::String
attribute :attr02, Types::String.optional
attribute? :attr03, Types::String
attribute :attr04, Types::Integer
attribute :attr05, Types::Date
attribute :attr06, Types::Array.of(Types::String)
attribute :attr07, Types.Constructor(User)
attribute :attr08, Types::String | Types::Integer
attribute :attr09, Types::Maybe::String
end
the compiler generates a rbi file below.
class Example
sig { returns(String) }
def attr01; end
sig { returns(T.nilable(String)) }
def attr02; end
sig { returns(T.nilable(String)) }
def attr03; end
sig { returns(Integer) }
def attr04; end
sig { returns(Date) }
def attr05; end
sig { returns(T::Array[String]) }
def attr06; end
sig { returns(User) }
def attr07; end
sig { returns(T.any(String, Integer)) }
def attr08; end
sig { returns(T.any(Dry::Monads::Maybe::Some, Dry::Monads::Maybe::None)) }
def attr09; end
end
Installation
Add this line to your application’s Gemfile:
gem 'tapioca-compilers-dry_struct'
And then execute:
$ bundle
all the gem needs to do is to place the DSL compiler inside the lib/tapioca/dsl/compilers folder and it will be automatically discovered and loaded by Tapioca.
https://github.com/Shopify/tapioca/blob/v0.10.2/README.md#writing-custom-dsl-compilers
Tapioca automatically load the compiler inside gem, just you need to do is type a command below.
$ bundle exec tapioca dsl
Development
Execute ./bin/dsl
generates rbi files under sorbet/rbi/dsl/
.
If you need to test another dry-struct, add or edit rb files under spec/examples/
and generate rbi files.
A compiler itself exists in lib/tapioca/dsl/compilers/dry_struct.rb
.
Test
bundle exec rake spec
Environment Variables
You can change behaviours of the compiler by environment variables.
DRY_PREFER_PLAIN_TIME
\ | Ruby Time is typed as |
---|---|
0 (DEFAULT) | ::ActiveSupport::TimeWithZone |
1 | ::Time |
DRY_USE_EXPERIMENTAL_SHAPE
\ |
Types::Hash.schema(name: Types::String, age: Types::Integer) is typed as |
---|---|
0 (DEFAULT) | ::T::Hash[::T.untyped, ::T.untyped] |
1 | { name: ::String, age: ::Integer } |
References
https://discourse.dry-rb.org/t/dry-rb-sorbet-can-we-unite/961