-1

I have a list of possible subcategory values, plus a list of subcategory grouping values that need to be associated. The user will enter a sub category value (Does this have to be an integer?) I need to check that this value is in the enum, but don't know what should be done if it isn't.

  1. Is there an "automatic" way of doing this check? Do we have to do this programmatically implementing the test on the enum?
  2. If the subcategory is used in a grouping category, how can it be used? How can it be set, how can it be read?

I'm thinking that the enums relationship would be something like this:

#[derive(Debug)]
pub enum Subtypes {
    acost,
    bcost,
    //... other subtypes
}

#[derive(Debug)]
pub enum Grouping {
    Exp(Subtypes),
    //...other grouping associated with different subtypes
}

How do I define a new variable based on the grouping enum, and how can it be accessed?

// this doesn't work!!
let group = Grouping::Exp;

I think I'm missing something really fundamental. I don't know if enums are the way to go.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
T9b
  • 3,312
  • 5
  • 31
  • 50
  • 3
    I really would recommend you to read [the book](https://doc.rust-lang.org/stable/book/), especially the chapter about [enums](https://doc.rust-lang.org/stable/book/ch06-00-enums.html) – hellow Dec 11 '18 at 14:15
  • 5
    I have no idea what you are trying to ask. Have you [read *The Rust Programming Language*](https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html)? It explains basic concepts, like the appropriate syntax for an enum with values: `Grouping::Exp(Subtypes::acost)` – Shepmaster Dec 11 '18 at 14:15
  • 2
    Idiomatic Rust uses `snake_case` for variables, methods, macros, and fields; `UpperCamelCase` for types and enum variants; and `SCREAMING_SNAKE_CASE` for statics and constants. Use `Acost` / `Bcost` instead, please. – Shepmaster Dec 11 '18 at 14:15
  • 1
    *don't know what should be done if it isn't* — this is not something we can help you with. Deciding on how to handle an error is vitally tied to your specific program and any potential users. – Shepmaster Dec 11 '18 at 14:17
  • @Shepmaster enums set out a series of known values. You can build a further enum referring to the first as a type, per my example. This compiles without issue. In your example `Grouping::Exp(Subtypes::acost)` you presume that I only wish to access one value, but in fact the enum `Grouping::Exp` refers to multiple values. The book does not explain how to expose those multiple values. – T9b Dec 11 '18 at 14:41
  • 2
    *in fact the enum `Grouping::Exp` refers to multiple values* — what do you mean by this? A variable can only be one specific value at a time, not some "quantum superposition" of multiple. – Shepmaster Dec 11 '18 at 14:51
  • @Shepmaster because `Grouping::Exp` has the type `Subtypes`. Therefore it must refer to multiple possible values. This compiles without error, therefore I presume it isn't doing anything impossible. – T9b Dec 11 '18 at 14:57
  • *this doesn't work!!* vs, *This compiles without error* — perhaps you can expand on your example to make it clear what you are trying to do and **how** it doesn't work? Maybe write some pseudocode that shows what logic you want? – Shepmaster Dec 11 '18 at 14:59
  • *if user input value exists in `Subtypes`* — user input is a binary blob or maybe a string; neither of those are an enum or enum variant. Therefore, no user input is ever in your enum, the "true" case cannot ever happen, and your conditional isn't needed. – Shepmaster Dec 11 '18 at 15:01
  • Is *that* what your question is — are you asking how to convert user input into one of your own enum variants? – Shepmaster Dec 11 '18 at 15:05
  • 1
    If so, then I think your question is answered by [How to convert a string to an enum?](https://stackoverflow.com/q/36508580/155423) or [Can I convert a string to enum without macros in Rust?](https://stackoverflow.com/q/39070244/155423) – Shepmaster Dec 11 '18 at 15:14

1 Answers1

1

You are right with enums you can embedded additional data in an enum. I am thinking you will need to follow a similar pattern.

Here's some code to help explain, taken from a GitHub repo. First, we embed a struct in an enum:

struct ConsoleOutput {}

pub enum OutputTypes {
    Console(ConsoleOutput),
}

This isn't enough to make it usable; for starters, a factory is needed. The factory actually allocates the structure that is embedded in the enum:

pub struct OutputFactory {}

impl OutputFactory {
    pub fn get() -> OutputTypes {
        OutputTypes::Console(ConsoleOutput {})
    }
}

The actual implementation is a little bit more involved.

After that, a trait is implemented on the enum and the trait contains the logic. I am thinking this is the area you need to work in.

pub struct ShellTypes {}

pub trait OutputTrait {
    fn generate(&self) -> ShellTypes;
}

impl OutputTrait for OutputTypes {
    fn generate(&self) -> ShellTypes {
        match *self {
            _ => return ShellTypes {},
        }
    }
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
i.do.stuff
  • 207
  • 3
  • 11
  • 1
    *taken from a GitHub repo* — if you are copying code from another source, the least you can do is link to it. – Shepmaster Dec 11 '18 at 21:49
  • *`return ShellTypes`* — this isn't idiomatic; there's no need for the `return`. Also the `*` in `*self` isn't needed. – Shepmaster Dec 12 '18 at 00:37