Is it possible to add type of constant values in struct?

I wanna make a function that only takes const values that are defined in the Container impl block. Is it possible to do that?
The reason why I wanna do it is that Rust doesn't support __call__ like Python if I understand Rust correctly.

struct Container;

impl Container {
    const CON_A: &static str = "a";
    const CON_B: &static str = "b";
  
    // this function just want to take constant value here (CON_A or CON_B)
    fn call(const_val_of_container: ???) { // <- what type should it be?
        todo!();
    }
}

fn main() {
    Container::call("a"); // <- should be error
    Container::call(Container:: CON_A); // should be good
}

Thanks!

rust is statically typed, and the type checker uses strict rules to ensure type safety. you can use a dedicated type (e.g. define a custom type or a newtype wrapper) for the constants and parameter type.

but I feel this is probably an XY problem. what's the actual problem you are trying to solve? a concrete example would explain the problem better.

3 Likes

The most direct translation of your given code is probably something like this, but it's a very unusual pattern— I suspect that there is a better way to solve whatever problem you have that led you to seek this solution.

struct Container;
struct A;
struct B;

// This is a trait of `Container` so that orphan rules prevent external implementations
trait ConstArg<T> {
    const ARG: &'static str;
}

impl Container {
    fn call<T>() where Self: ConstArg<T> {
        let const_val_of_container = <Self as ConstArg<T>>::ARG;
        todo!();
    }
}

impl ConstArg<A> for Container {
    const ARG: &'static str = "a";
}

impl ConstArg<B> for Container {
    const ARG: &'static str = "b";
}

fn main() {
    Container::call::<A>();
}
1 Like

Or maybe, you're looking for something like an enum? I'm just guessing here...

struct Container;
#[derive(Copy,Clone)]
enum ContainerArgs { A, B };

impl ContainerArgs {
    const fn as_str(self)->&'static str {
        match self {
            Self::A => "a",
            Self::B => "b"
        }
    }
}

impl Container {
    fn call(arg: ContainerArgs) {
        let const_val_of_container = arg.as_str();
        todo!();
    }
}

fn main() {
   Container::call(ContainerArgs::A);
}
3 Likes

I am trying to fetch data from GraphQL without using libraries, but looks like using libraries iseems easier than implementing it myself.

This is clean! I like it. I probably wouldn't use it this time because I've decided to use GraphQL library but I'll keep it in mind. Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.