Then there is a BlastJob::launch() method the unconditionally fills the last three fields and other methods write and read them, but if course I have to wrap and unwrap the values.
Would it be too unidiomatic (or may be the right form?) to declare de struct as:
Rust has a concept of a Default value. You can implement Default trait for a struct, and then create an object with Default::default(), and also use it to fill in rest of the fields using .. struct operator.
Yes, I can implement Default and let BlastJob::new() return SomeOptions { send_job_url, ..Default::default() }
But my dilemma stays the same. Is it OK to use an empty string or a 0 to signal unset? Naturally I have to assure that the empty string or 0 have no other meaning that "unset".
The code will work either way, and this is a small self contained program so I'm comfortable storing the two concepts in a non Option variable (the value itself and whether it is something or not (Yes, for that reason we have Option::Some() and Option::None))
I just wondered if such code is an eyesore for a seasoned Rustician.
To be honest, the most idiomatic thing in Rust is to not have an unset variable.
Instead, you should only create the BlastJob once all of its constituent parts have been created. That way you can always assume that the BlastJob is ready to be used and in a valid state, instead of being in a kinda-sorta-initialized intermediate state like you get in object constructors for OO languages.
You may want to look into the builder pattern where you have a builder type with a lot of Option fields, and then some way to convert that into your BlastJob with no Options wherein you know the fields have been set. There will be various considerations depending on your use case; it may or may not be a good fit depending on how exactly launch works in your case, for example.