Search code examples
rustbuilder

How to set the default value of the following struct field?


Here, description and prompt are optional, so their default value is None.

#[derive(Debug, Default)]
pub struct Keymap {
    pub key: char,
    pub command: String,
    pub description: Option<String>,
    pub prompt: Option<String>,
}

impl Keymap {
    pub fn new<S: AsRef<str>>(key: char, command: S) -> Self {
        Self {
            key,
            command: command.as_ref().to_owned(),
            ..Default::default()
        }
    }

    pub fn with_prompt<S: AsRef<str>>(mut self, prompt: S) -> Self {
        self.prompt = Some(prompt.as_ref().to_owned());
        self
    }

    pub fn with_description<S: AsRef<str>>(mut self, description: S) -> Self {
        self.description = Some(description.as_ref().to_owned());
        self
    }
}

fn main() {
    let keymap = Keymap::new('a', "echo Hello, World!")
        .with_prompt("Enter your name:")
        .with_description("Prints 'Hello, World!'");

    println!("{:?}", keymap);
}

Rust Playground

But I want description's fallback value to be the value of command. If a description is provided, then that value should be used.

How to accomplish that?


Solution

  • But I want description's default value to be the value of command.

    impl Keymap {
        pub fn new<S: AsRef<str>>(key: char, command: S) -> Self {
            let command = command.as_ref().to_string();
            Self {
                key,
                description: Some(command.clone()),
                command,
                ..Default::default()
            }
        }
    }
    

    ?

    Not sure why description would still be an Option tho.

    Alternatively, just fallback on the consumer side.

    If you're asking if there's a way to make description magically be a copy of command unless it's explicitly set, then no. Though you could emulate that by keeping description private and accessing it via a method e.g.

        pub fn description(&self) -> &str {
            self.description.as_deref().unwrap_or(&self.command)
        }
    

    in which case you may want to impl Debug by hand.