RFC: trick to avoid funcname(bool, bool, bool)


I have a function which needs a few boolean values. To avoid call sites looking like

x = blah (true, false, true);

where one would have no idea of what the arguments represent, I came up with the following:

pub enum Fubarize {

pub enum Frobnify {

pub fn blah (fubarize: Fubarize, frobnify: Frobnify) -> i32 {
  if fubarize == Fubarize::Yes {

This is a bit awkward in the implementation, but I really like the callers looking like

x = blah (Fubarize::Yes, Frobnify::No);

Alternative: newtypes on booleans, so you’d have

pub struct Fubarize(bool);
pub struct Frobnify(bool);

x = blah (Fubarize (true), Frobnify(false));

Opinions, or suggestions about different patterns, are appreciated!


You can get around providing the #[derive(PartialEq)] by using if let:

pub fn blah (fubarize: Fubarize, frobnify: Frobnify) -> i32 {
  if let Fubarize::Yes = fubarize {

which is equivalent to

pub fn blah (fubarize: Fubarize, frobnify: Frobnify) -> i32 {
  match fubarize {
      Fubarize::Yes => {
      _ => (),


Personally, I think bitflags would be more ergonomic/concise and still quite readable. Multiple newtype wrappers over bool for this purpose seems excessive. Also, it’d be nice if Rust picks up named args at some point.


Passing the named arguments with a struct works well.


An IDE that gives you the details quick is best.

x = blah({let x=true;x}, {let y=false;y}, {let z=true;z});
or switch to const with added type.


(responding to @jonh, the software doesn’t make it really clear when the post is directly following)

That’s so weird of a hack that you may as well do.

let x = true;
let y = false;
let z = true;
let x = blah(x, y, z);


Although, considering this is a C style enum, why not just use #[derive(Eq, PartialEq)] :slight_smile:. It’s not that it may suddenly change to have fields that don’t implement Eq.


@federicomenaquintero For what it’s worth I like your newtypes alternative the best. It looks like the simplest to implement and cleanest to read.


You can also write:

struct Fubarize(bool);
struct Frobnify(bool);

fn blah(Fubarize(fub): Fubarize, Frobnify(frob): Frobnify) {
    println!("{} {}", fub, frob);

fn main() {
    blah(Fubarize(true), Frobnify(false));

But this is more verbose and less DRY than nice named arguments.


TIL that function arguments are also pattern matches. Thanks!


Yes, but they can only be used with so-called irrefutable patterns, so a tuple or a struct works, but not an enum, just like in let.