I'm trying to use the nannou crate to randomly generate symbols, but I'm having trouble writing a function that randomly generates a symbol and stores it into the following struct
struct Sigil<T,U>{
major:Drawing<'static,T>,
minor:Vec<Drawing<'static,U>>
}
i tried to do the following
fn sigil_make<T,U>(app: &App)->Sigil<T,U>{
let draw=app.draw();
let mut sigil:Sigil<T,U>;
match random::<u8>()%2 {
0=>sigil.major=draw.ellipse(),
1=>sigil.major=draw.polygon(),
_=>println!("uh oh")
}
return sigil;
}
but this doesn't work as major is expecting type T while I'm trying to set it to a shape from nannou.
what would be the appropriate way to go about doing this?
There's several problems all at once here. I will list them along with the possible solutions.
T
, but your function already knows the type itself.
T
parameter. (It may make sense for the caller to specify what U
is since your function does not.)Box<dyn _>
with a trait) or an "either" type, such as an enum with a variant for each possible returned type.Draw
returned by app.draw()
, but the Draw
will be destroyed when the function returns.
&Draw
instead of an &App
, which will give you a longer-lived Draw
to borrow from._
arm of your match
needs to evaluate as something of the same type as well.
Option
. Since another value should not be possible, we can panic by using the built-in unreachable!
macro.1
arm to _
.Sigil
; the minor
field is not initialized and so you cannot return it.
minor
as well.Sigil
specifies that the lifetimes of the Drawing
values are 'static
, which is not guaranteed to be true.
Sigil
.Here's an example of how you could solve these issues:
struct Sigil<'a, T, U> {
major: Drawing<'a, T>,
minor: Vec<Drawing<'a, U>>,
}
// See also the "either" crate, which provides an enum like this.
enum Either<L, R> {
Left(L),
Right(R),
}
fn sigil_make<U>(draw: &Draw) -> Either<Sigil<'_, Ellipse, U>, Sigil<'_, PolygonInit, U>> {
match random::<u8>() % 2 {
0 => Either::Left(Sigil {
major: draw.ellipse(),
minor: vec![],
}),
_ => Either::Right(Sigil {
major: draw.polygon(),
minor: vec![],
}),
}
}