Are they some code sample of hierarchical Dry::Struct?


#1

Does someone has sample code to share of Dry::Struct with hierarchical attributes ?

I’m trying some initialisation code around lines like :

module Config
  class Sidekiq < Dry::Struct
      constructor_type :schema
      attribute :redis, Dry::Types['optional.strict.hash'].schema(
          # not recommended for redis (lower speed),
          # but if we need several *segregated* cubes
          # we could namespace them (i.e all redis keys will be prefixed)
          :namespace, Dry::Types['strict.string'].optional,
          # If your client is single-threaded, we just need a single connection in our Redis connection pool
          :size, Dry::Types['coercible.int'].default(1)
      )
  end
end

but I got exception as #schema do not expect such signature
and if I use a Dry::Types['optional.strict.hash'].schema([ tuples of id, type]) the initialisation of type think this is a Dry::Sum type.

I thought that this use case, could be better read with a &block to yield like

module Config
  class Sidekiq < Dry::Struct
      constructor_type :schema
      attribute :redis, Dry::Types['optional.strict.hash'] do 
          :namespace, Dry::Types['strict.string'].optional,
          :size, Dry::Types['coercible.int'].default(1)
      end

that will latter deliver .dot accessors like myconfig.redis.namespace or myconfig[:redis][:namespace]

I used to do a lot config -> actual Class like this using variations of Hashie/Mashie or using Representable
it could be interesting to have the same kind of hierarchical structuration in Dry::Struct

For now I don’t see #schema usage even on ‘big’ sample like Berg


#2

You can use a struct inside a struct, this will give a more predictable behavior tbh

module Config
  class Sidekiq < Dry::Struct
    class RedisConfig < Dry::Struct
      constructor_type :schema

      attribute :namespace, Dry::Types['strict.string'].optional
      attribute :size, Dry::Types['coercible.int'].default(1)
    end

    constructor_type :schema

    attribute :redis, RedisConfig
  end
end

#3

lovely !!!

Thanks I’ll try this right away :wink: