I wish to define a function that inspects two values and optionally changes one of them into a matching type. The motivation is to perform automatic casting for math formulas. My rules would be:
- Both are
i64
, leave alone - Both are
f64
, leave alone - One is
i64
, one isf64
, change thei64
tof64
- Other rules for other types
For example:
fn normalize(arg1: Option<MyValue>, arg2: Option<MyValue>) -> (Option<MyValue>, Option<MyValue>) {
unimplemented!();
}
My example will return a tuple with the optionally transformed values. MyValue
does not implement Copy
, but it does implement Clone
. It is an enum which can hold an integer or a rational or a string, etc.
The alternatives I can see are:
- Return a tuple. Transform the value that needs to change, clone the other to avoid borrow-checker. Conversion failures come back as
None
. - Return a tuple. Transform the value that needs to change, return the other one unchanged, figure out how to move the value.
- Return
()
. Make the parameters&mut
. Change the one that needs to change, if any. - Some other way that I do not know about, because I am new to Rust.
Which approach is most idiomatic to Rust? If I do not clone, how do I notate the signature to placate the borrow-checker?
My real enum is:
#[derive(Clone, PartialEq, Debug)]
pub enum ShyScalar {
Boolean(bool),
Integer(i64),
Rational(f64),
String(String),
Error(String)
}