Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: A pattern matching option #41

Closed
jwoertink opened this issue May 30, 2019 · 5 comments · Fixed by #49
Closed

Feature: A pattern matching option #41

jwoertink opened this issue May 30, 2019 · 5 comments · Fixed by #49

Comments

@jwoertink
Copy link
Member

I was just thinking about an option that might be kind of cool. Let's say you have a class like this where you need to configure a code that looks like a number

class Config
  Habitat.create do
    setting code : Int32
  end
end

You can use Int32 here which is nice, but if you set the value to ENV["CODE"], you'll get an error because crystal will see that env var as a string. So you have to cast it. But what happens if you expect this code to be exactly 4 digits like a PIN, and it starts with 0? You'd need to set it as a String in this case. setting code : String, example: "4 digit number". This works fine, but if a space gets in there, or any other number of things could cause some issues.

Now, how about an option like match or something where you could do this?

class Config
  Habitat.create do
    setting code : String, match: /^\d{4}$/, example: "1234"
  end
end

This could probably add something to the setter where if the value doesn't match, it raises an exception. I think this could help catch a few configuration setup errors where things need to look a specific way

@paulcsmith
Copy link
Member

@jwoertink Just now seeing this 🤣 I thin this is a great use-case but I'd love it to be even more flexible by passing the name of a method that will be called with the value:

class Config
  Habitat.create do
    setting code : Int32, example: "1234", parse_with: :parse_otp_code
  end

  def self.parse_otp_code(value : String) : Int32
    # This probably doesn't work, but this shows the idea. Validation + parsing
    value.match(/^\d{4}$/) || invalid("Number must be 4 digits long")
  end
end

Thoughts?
Or something along those lines. That way you can share validations, use shards, etc.

@jwoertink
Copy link
Member Author

Even better flexibility! Love it. I wonder if this could be caught at compile-time, or if it would have to be run-time with how it's built 🤔

@paulcsmith
Copy link
Member

Glad you like it! I think it'd have to be runtime since it is parsing the env/string at runtime, but maybe I am misunderstanding which part you meant

@jwoertink
Copy link
Member Author

No, you got it. That makes sense. I just love when things are compile-time catches though 😅

@paulcsmith
Copy link
Member

Not me. Fail at runtime, every time 💣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants