shale-builder 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +140 -35
- data/lib/shale/builder/version.rb +1 -1
- data/lib/tapioca/dsl/compilers/shale.rb +32 -4
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a1194476cdc1f12fedaee4208834a474caf3397d0b4cab907f20648d5e812394
         | 
| 4 | 
            +
              data.tar.gz: ce1363ceced738925bbe89abc807daa9e7cc54099244181083e0c35364d5c76d
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 8fb3b29c2765d93b8cbcdd35ec04085d50bbc918bb6c5e2bec62ce80cfeb75d2af3a815956b68d31b882e7c46db8929f48039cb8a0880b4b50766581de0a811d
         | 
| 7 | 
            +
              data.tar.gz: 3e2c7f826e65b70ac6c2efca789b836ac476594bee5e93d265c56a88f9ec2921fdff7a5352baf33a2ca1a887efdb824d24b2335481fb9fb5bda64547e69c7b05
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -51,11 +51,7 @@ class Amount < Shale::Mapper | |
| 51 51 | 
             
                include Shale::Builder
         | 
| 52 52 |  | 
| 53 53 | 
             
                attribute :value, Shale::Type::Float
         | 
| 54 | 
            -
                attribute :currency, Shale::Type::String | 
| 55 | 
            -
                    This is some custom documentation that can be used by sorbet.
         | 
| 56 | 
            -
                    It will be used by the tapioca DSL compiler
         | 
| 57 | 
            -
                    to generate the RBI documentation for this attribute.
         | 
| 58 | 
            -
                DOC
         | 
| 54 | 
            +
                attribute :currency, Shale::Type::String
         | 
| 59 55 | 
             
            end
         | 
| 60 56 | 
             
            ```
         | 
| 61 57 |  | 
| @@ -74,36 +70,6 @@ amount = Amount.build do |a| | |
| 74 70 | 
             
            end
         | 
| 75 71 | 
             
            ```
         | 
| 76 72 |  | 
| 77 | 
            -
            If you use sorbet and run `bundle exec tapioca dsl` you'll get the following RBI file.
         | 
| 78 | 
            -
             | 
| 79 | 
            -
            ```rb
         | 
| 80 | 
            -
            # typed: true
         | 
| 81 | 
            -
             | 
| 82 | 
            -
            class Amount
         | 
| 83 | 
            -
              include ShaleAttributeMethods
         | 
| 84 | 
            -
             | 
| 85 | 
            -
              module ShaleAttributeMethods
         | 
| 86 | 
            -
                sig { returns(T.nilable(Float)) }
         | 
| 87 | 
            -
                def value; end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                sig { params(value: T.nilable(Float)).returns(T.nilable(Float)) }
         | 
| 90 | 
            -
                def value=(value); end
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                # This is some custom documentation that can be used by sorbet.
         | 
| 93 | 
            -
                # It will be used by the tapioca DSL compiler
         | 
| 94 | 
            -
                # to generate the RBI documentation for this attribute.
         | 
| 95 | 
            -
                sig { returns(T.nilable(String)) }
         | 
| 96 | 
            -
                def currency; end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                # This is some custom documentation that can be used by sorbet.
         | 
| 99 | 
            -
                # It will be used by the tapioca DSL compiler
         | 
| 100 | 
            -
                # to generate the RBI documentation for this attribute.
         | 
| 101 | 
            -
                sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
         | 
| 102 | 
            -
                def currency=(value); end
         | 
| 103 | 
            -
              end
         | 
| 104 | 
            -
            end
         | 
| 105 | 
            -
            ```
         | 
| 106 | 
            -
             | 
| 107 73 | 
             
            ### Building nested objects
         | 
| 108 74 |  | 
| 109 75 | 
             
            It's kind of pointless when you've got a flat structure.
         | 
| @@ -247,6 +213,145 @@ transaction = Transaction.build do |t| | |
| 247 213 | 
             
            end
         | 
| 248 214 | 
             
            ```
         | 
| 249 215 |  | 
| 216 | 
            +
            ### Sorbet support
         | 
| 217 | 
            +
             | 
| 218 | 
            +
            Shale-builder adds support for sorbet and tapioca.
         | 
| 219 | 
            +
             | 
| 220 | 
            +
            You can leverage an additional `doc` keyword argument in `attribute` definitions.
         | 
| 221 | 
            +
            It will be used to generate a comment in the RBI file.
         | 
| 222 | 
            +
             | 
| 223 | 
            +
            ```rb
         | 
| 224 | 
            +
            require 'shale/builder'
         | 
| 225 | 
            +
             | 
| 226 | 
            +
            class Amount < Shale::Mapper
         | 
| 227 | 
            +
                include Shale::Builder
         | 
| 228 | 
            +
             | 
| 229 | 
            +
                attribute :value, Shale::Type::Float
         | 
| 230 | 
            +
                attribute :currency, Shale::Type::String, doc: <<~DOC
         | 
| 231 | 
            +
                    This is some custom documentation that can be used by sorbet.
         | 
| 232 | 
            +
                    It will be used by the tapioca DSL compiler
         | 
| 233 | 
            +
                    to generate the RBI documentation for this attribute.
         | 
| 234 | 
            +
                DOC
         | 
| 235 | 
            +
            end
         | 
| 236 | 
            +
            ```
         | 
| 237 | 
            +
             | 
| 238 | 
            +
            If you use sorbet and run `bundle exec tapioca dsl` you'll get the following RBI file.
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            ```rb
         | 
| 241 | 
            +
            # typed: true
         | 
| 242 | 
            +
             | 
| 243 | 
            +
            # DO NOT EDIT MANUALLY
         | 
| 244 | 
            +
            # This is an autogenerated file for dynamic methods in `Amount`.
         | 
| 245 | 
            +
            # Please instead update this file by running `bin/tapioca dsl Amount`.
         | 
| 246 | 
            +
             | 
| 247 | 
            +
            class Amount
         | 
| 248 | 
            +
              include ShaleAttributeMethods
         | 
| 249 | 
            +
             | 
| 250 | 
            +
              module ShaleAttributeMethods
         | 
| 251 | 
            +
                sig { returns(T.nilable(Float)) }
         | 
| 252 | 
            +
                def value; end
         | 
| 253 | 
            +
             | 
| 254 | 
            +
                sig { params(value: T.nilable(Float)).returns(T.nilable(Float)) }
         | 
| 255 | 
            +
                def value=(value); end
         | 
| 256 | 
            +
             | 
| 257 | 
            +
                # This is some custom documentation that can be used by sorbet.
         | 
| 258 | 
            +
                # It will be used by the tapioca DSL compiler
         | 
| 259 | 
            +
                # to generate the RBI documentation for this attribute.
         | 
| 260 | 
            +
                sig { returns(T.nilable(String)) }
         | 
| 261 | 
            +
                def currency; end
         | 
| 262 | 
            +
             | 
| 263 | 
            +
                # This is some custom documentation that can be used by sorbet.
         | 
| 264 | 
            +
                # It will be used by the tapioca DSL compiler
         | 
| 265 | 
            +
                # to generate the RBI documentation for this attribute.
         | 
| 266 | 
            +
                sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
         | 
| 267 | 
            +
                def currency=(value); end
         | 
| 268 | 
            +
              end
         | 
| 269 | 
            +
            end
         | 
| 270 | 
            +
            ```
         | 
| 271 | 
            +
             | 
| 272 | 
            +
            #### Primitive types
         | 
| 273 | 
            +
             | 
| 274 | 
            +
            If you define custom primitive types in Shale by inheriting from `Shale::Type::Value`
         | 
| 275 | 
            +
            you can describe the return type of the getter of the field that uses this primitive type by defining the `return_type` method that returns a sorbet type.
         | 
| 276 | 
            +
             | 
| 277 | 
            +
            ```rb
         | 
| 278 | 
            +
            def self.return_type = T.nilable(String)
         | 
| 279 | 
            +
            ```
         | 
| 280 | 
            +
             | 
| 281 | 
            +
            You can also describe the accepted argument type in the setter by defining the `setter_type` method that returns a sorbet type.
         | 
| 282 | 
            +
             | 
| 283 | 
            +
            ```rb
         | 
| 284 | 
            +
            def self.setter_type = T.any(String, Float, Integer)
         | 
| 285 | 
            +
            ```
         | 
| 286 | 
            +
             | 
| 287 | 
            +
            Here is a full example.
         | 
| 288 | 
            +
             | 
| 289 | 
            +
            ```rb
         | 
| 290 | 
            +
            # typed: true
         | 
| 291 | 
            +
            require 'shale/builder'
         | 
| 292 | 
            +
             | 
| 293 | 
            +
            # Cast from XML string to BigDecimal.
         | 
| 294 | 
            +
            # And from BigDecimal to XML string.
         | 
| 295 | 
            +
            class BigDecimalShaleType < Shale::Type::Value
         | 
| 296 | 
            +
                class << self
         | 
| 297 | 
            +
                    extend T::Sig
         | 
| 298 | 
            +
             | 
| 299 | 
            +
                    # the return type of the field that uses this class as its type
         | 
| 300 | 
            +
                    def return_type = T.nilable(BigDecimal)
         | 
| 301 | 
            +
                    # the type of the argument given to a setter of the field
         | 
| 302 | 
            +
                    # that uses this class as its type
         | 
| 303 | 
            +
                    def setter_type = T.any(BigDecimal, String, NilClass)
         | 
| 304 | 
            +
             | 
| 305 | 
            +
                    # Decode from XML.
         | 
| 306 | 
            +
                    sig { params(value: T.any(BigDecimal, String, NilClass)).returns(T.nilable(BigDecimal)) }
         | 
| 307 | 
            +
                    def cast(value)
         | 
| 308 | 
            +
                        return if value.nil?
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                        BigDecimal(value)
         | 
| 311 | 
            +
                    end
         | 
| 312 | 
            +
             | 
| 313 | 
            +
                    # Encode to XML.
         | 
| 314 | 
            +
                    #
         | 
| 315 | 
            +
                    # @param value: Value to convert to XML
         | 
| 316 | 
            +
                    sig { params(value: T.nilable(BigDecimal)).returns(T.nilable(String)) }
         | 
| 317 | 
            +
                    def as_xml_value(value)
         | 
| 318 | 
            +
                        return if value.nil?
         | 
| 319 | 
            +
             | 
| 320 | 
            +
                        value.to_s('F')
         | 
| 321 | 
            +
                    end
         | 
| 322 | 
            +
                end
         | 
| 323 | 
            +
            end
         | 
| 324 | 
            +
             | 
| 325 | 
            +
            class Amount < Shale::Mapper
         | 
| 326 | 
            +
                include Shale::Builder
         | 
| 327 | 
            +
             | 
| 328 | 
            +
                # `value` uses BigDecimalShaleType as its type
         | 
| 329 | 
            +
                attribute :value, BigDecimalShaleType
         | 
| 330 | 
            +
            end
         | 
| 331 | 
            +
            ```
         | 
| 332 | 
            +
             | 
| 333 | 
            +
            After running `bundle exec tapioca dsl` you'll get the following RBI file.
         | 
| 334 | 
            +
             | 
| 335 | 
            +
            ```rb
         | 
| 336 | 
            +
            # typed: true
         | 
| 337 | 
            +
             | 
| 338 | 
            +
            # DO NOT EDIT MANUALLY
         | 
| 339 | 
            +
            # This is an autogenerated file for dynamic methods in `Amount`.
         | 
| 340 | 
            +
            # Please instead update this file by running `bin/tapioca dsl Amount`.
         | 
| 341 | 
            +
             | 
| 342 | 
            +
            class Amount
         | 
| 343 | 
            +
              include ShaleAttributeMethods
         | 
| 344 | 
            +
             | 
| 345 | 
            +
              module ShaleAttributeMethods
         | 
| 346 | 
            +
                sig { returns(T.nilable(::BigDecimal)) }
         | 
| 347 | 
            +
                def value; end
         | 
| 348 | 
            +
             | 
| 349 | 
            +
                sig { params(value: T.nilable(T.any(::BigDecimal, ::String))).returns(T.nilable(T.any(::BigDecimal, ::String))) }
         | 
| 350 | 
            +
                def value=(value); end
         | 
| 351 | 
            +
              end
         | 
| 352 | 
            +
            end
         | 
| 353 | 
            +
            ```
         | 
| 354 | 
            +
             | 
| 250 355 | 
             
            ## Development
         | 
| 251 356 |  | 
| 252 357 | 
             
            After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         | 
| @@ -37,7 +37,7 @@ module Tapioca | |
| 37 37 | 
             
                      attribute_names = constant.attributes.keys.sort
         | 
| 38 38 | 
             
                      attribute_names.each do |attribute_name|
         | 
| 39 39 | 
             
                        attribute = T.let(constant.attributes[attribute_name], ::Shale::Attribute)
         | 
| 40 | 
            -
                        non_nilable_type, nilable_type =  | 
| 40 | 
            +
                        non_nilable_type, nilable_type = shale_type_to_sorbet_return_type(attribute)
         | 
| 41 41 | 
             
                        type = nilable_type
         | 
| 42 42 | 
             
                        if attribute.collection?
         | 
| 43 43 | 
             
                          type = "T.nilable(T::Array[#{non_nilable_type}])"
         | 
| @@ -69,6 +69,12 @@ module Tapioca | |
| 69 69 | 
             
                          mod.create_method(attribute.name, return_type: type, comments: comments)
         | 
| 70 70 | 
             
                        end
         | 
| 71 71 |  | 
| 72 | 
            +
                        non_nilable_type, nilable_type = shale_type_to_sorbet_setter_type(attribute)
         | 
| 73 | 
            +
                        type = nilable_type
         | 
| 74 | 
            +
                        if attribute.collection?
         | 
| 75 | 
            +
                          type = "T.nilable(T::Array[#{non_nilable_type}])"
         | 
| 76 | 
            +
                        end
         | 
| 77 | 
            +
             | 
| 72 78 | 
             
                        # setter
         | 
| 73 79 | 
             
                        mod.create_method(
         | 
| 74 80 | 
             
                          "#{attribute.name}=",
         | 
| @@ -106,22 +112,44 @@ module Tapioca | |
| 106 112 | 
             
                  )
         | 
| 107 113 |  | 
| 108 114 | 
             
                  sig { params(attribute: ::Shale::Attribute).returns([String, String]) }
         | 
| 109 | 
            -
                  def  | 
| 115 | 
            +
                  def shale_type_to_sorbet_return_type(attribute)
         | 
| 110 116 | 
             
                    return_type = SHALE_TYPES_MAP[attribute.type]
         | 
| 111 | 
            -
                    return  | 
| 117 | 
            +
                    return complex_shale_type_to_sorbet_return_type(attribute) unless return_type
         | 
| 112 118 | 
             
                    return [T.must(return_type.name), T.must(return_type.name)] if attribute.collection? || attribute.default.is_a?(return_type)
         | 
| 113 119 |  | 
| 114 120 | 
             
                    [T.must(return_type.name), "T.nilable(#{return_type.name})"]
         | 
| 115 121 | 
             
                  end
         | 
| 116 122 |  | 
| 117 123 | 
             
                  sig { params(attribute: ::Shale::Attribute).returns([String, String]) }
         | 
| 118 | 
            -
                  def  | 
| 124 | 
            +
                  def complex_shale_type_to_sorbet_return_type(attribute)
         | 
| 119 125 | 
             
                    return [T.cast(attribute.type.to_s, String), "T.nilable(#{attribute.type})"] unless attribute.type.respond_to?(:return_type)
         | 
| 120 126 |  | 
| 121 127 | 
             
                    return_type_string = attribute.type.return_type.to_s
         | 
| 122 128 | 
             
                    [return_type_string, return_type_string]
         | 
| 123 129 | 
             
                  end
         | 
| 124 130 |  | 
| 131 | 
            +
                  sig { params(attribute: ::Shale::Attribute).returns([String, String]) }
         | 
| 132 | 
            +
                  def shale_type_to_sorbet_setter_type(attribute)
         | 
| 133 | 
            +
                    setter_type = SHALE_TYPES_MAP[attribute.type]
         | 
| 134 | 
            +
                    return complex_shale_type_to_sorbet_setter_type(attribute) unless setter_type
         | 
| 135 | 
            +
                    return [T.must(setter_type.name), T.must(setter_type.name)] if attribute.collection? || attribute.default.is_a?(setter_type)
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                    [T.must(setter_type.name), "T.nilable(#{setter_type.name})"]
         | 
| 138 | 
            +
                  end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                  sig { params(attribute: ::Shale::Attribute).returns([String, String]) }
         | 
| 141 | 
            +
                  def complex_shale_type_to_sorbet_setter_type(attribute)
         | 
| 142 | 
            +
                    if attribute.type.respond_to?(:setter_type)
         | 
| 143 | 
            +
                      setter_type_string = attribute.type.setter_type.to_s
         | 
| 144 | 
            +
                      [setter_type_string, setter_type_string]
         | 
| 145 | 
            +
                    elsif attribute.type.respond_to?(:return_type)
         | 
| 146 | 
            +
                      return_type_string = attribute.type.return_type.to_s
         | 
| 147 | 
            +
                      [return_type_string, return_type_string]
         | 
| 148 | 
            +
                    else
         | 
| 149 | 
            +
                      [T.cast(attribute.type.to_s, String), "T.nilable(#{attribute.type})"]
         | 
| 150 | 
            +
                    end
         | 
| 151 | 
            +
                  end
         | 
| 152 | 
            +
             | 
| 125 153 | 
             
                end
         | 
| 126 154 | 
             
              end
         | 
| 127 155 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: shale-builder
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.2.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Mateusz Drewniak
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024-06- | 
| 11 | 
            +
            date: 2024-06-11 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: booleans
         |