Skip to content
This repository was archived by the owner on Jan 2, 2021. It is now read-only.
This repository was archived by the owner on Jan 2, 2021. It is now read-only.

Custom State class #9

@z64

Description

@z64

Hey Sam, really been enjoying using Raze so far.

I wondered if you would humor the idea, for the future of Raze, to remove the existing ctx.state hash for a user-defined Raze::State. While the hash works, for more complicated applications it's not fun to work with ctx.state since the hash contains many additional added types via add_context_storage_type, and you have to do additional type reductions, i.e.

user_model = ctx.state["user"] #=> Nil, String, Int32, Int64, Float64, Bool.... and User
user_model.email # Won't compile
if user_model.is_a?(UserModel) # or .responds_to?(:email), etc
  # Type is reduced in here, but the programmer already knows this.. feels like "boilerplate"
  user_model # UserModel
  user_model.email # OK!
end

If we could define our own State for our app with its own property, combined with using assertions / other validation in middleware, the above code inside a route (after all middleware) could be simplified to ctx.state.user.email, since we can guarantee the User.

# in some middleware..
ctx.state.user = UserModel.maybe_find_user(name: "z64")
halt unless ctx.state.user
ctx.state.user.not_nil!
done.call

This is already possible by not using ctx.state at all and using my own methods to track state.. but this is of course coding around the library instead of using it :)

Thoughts? To me, the state hash feels like something brought over from Ruby frameworks that doesn't work well in Crystal (except for small apps that only use these primitive types, I guess).

Perhaps the add_context_storage_type macro could simply reopen Raze::State (an empty class) and add whatever property;

module Raze
  class State
  end

  macro add_state_property(prop)
    class State
      property {{prop}}
    end
  end

  add_state_property int : Int32 = 0

  p State.new.int # 0
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions