# Restrict \`OptionParser\` argument to enum values

**URL:** <https://forum.crystal-lang.org/t/restrict-optionparser-argument-to-enum-values/5267>\
**Category:** Help & Support\
**Created:** [January 14, 2023, 4:07pm UTC](https://forum.crystal-lang.org/t/restrict-optionparser-argument-to-enum-values/5267 "2023-01-14T16:07:35Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [January 14, 2023, 4:07pm UTC](https://forum.crystal-lang.org/t/restrict-optionparser-argument-to-enum-values/5267/1 "2023-01-14T16:07:35Z")

</div>

> [@More on Symbols](https://forum.crystal-lang.org/t/more-on-symbols/504/4):
>
> Please name a good reason _why_ this should be possible instead of turning the argument around?
> 
> In the way this would be implemented, there is no essential difference to simply use strings directly. It would just be a very similar alternative without any major benefits. And it makes it harder to use because people need to decide between both which can be very cumbersome.
> 
> In Ruby this is already known to be a problem which resulted in “solutions” like `HashWithIndifferentAccess`.  
> Without symbols, there wouldn’t be such problems in the first place.
> 
> Matz even tried to remove them from Ruby, but that would break to much code. In Crystal we can do so.
> 
> I know it seems hard at first. But when you think about it at bit longer, you’ll notice that you can do very well without symbols. I can’t remember having used a single symbol in Crystal for anything else than named tuples and autocasted enum values.

Hi, I have a quesiton, please help, thanks.

When i use OptionParser, i want to limit the users input with a Enum, how to do that?

e.g. check following code,

```crystal
parser.on(
      "-e ENGINE",
      "--engine=ENGINE",
      "Specify engine used for translate, support bing|youdao for now.
") do |e|
      case e
      when "bing"
        engine = "bing"
      when "youdao"
        engine = "youdao"
      else
        STDERR.puts "Supported options: -e bing|youado"
        exit
      end
    end

```

The user passed args with `-e ARGS` is a string, i have to raise a error to limit the user only can support `-e youdao` or `-e bing`, this really a case which enum be good at, right?

This is basically a question of user input working with enum, so, is it possible?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [January 15, 2023, 3:34am UTC](https://forum.crystal-lang.org/t/restrict-optionparser-argument-to-enum-values/5267/2 "2023-01-15T03:34:32Z")

</div>

Something like

```auto
unless engine = Engine.parse? e
  STDERR.puts "Supported options: #{Engine.names.map(&.downcase).join ", "}"
  exit 1
end

# ...

```
