r/learnrust • • 1d ago

Idiomatic way to initialise struct that could fail?

I want to initialise a struct from 3 or 4 parameters. Not sure which way to go : builder pattern, or wrap the parameters in a temporary struct and impl TryFrom.

I'm currently just using fn new(a, b, c)->Result<T> in an impl block but there should be a better way.

5 Upvotes

6 comments sorted by

11

u/fbpw131 1d ago

I noticed some libs use builder pattern + try_new/build method, but usually the options have sensible defaults.

If your struct has 3 mandatory fields, then a 3 arg new(a,b,c) method is a good fit. If you want to compose the args along the way, then a builder is suited.

1

u/woollufff 1d ago

Just 3 mandatory fields but some parsing and ordering (start and end parameters) hence returning a Result

6

u/fbpw131 1d ago

try_new

7

u/lotanis 1d ago

If all of the parameters are required then the function you've got is absolutely right.

The builder pattern is great when you've got lots of parameters THAT ARE OPTIONAL.

Rust doesn't have optional arguments, so you can't have functions like "open" in Python where there's one required arg (file path) and then everything else is defaults that you can optionally set.

If your function only takes a couple of arguments then you probably just want Option: "fn open(filename: &str, mode: Option<&str>)” and then you just pass None to mean "use default".

But if your function takes like 15 possible arguments that would get very annoying so that's when you have the builder pattern. The initial call to the builder has some arguments - those are the required arguments. Then the builder struct has default values for everything else, with methods to override the default.

1

u/Excession638 1d ago

That new function seems fine and normal to me. I would start worrying when it reached six parameters.

1

u/woollufff 1d ago

Thank you all for your replies