0xThylacine<p>That took *quite* some debugging.</p><p>I have a Mersenne Twister trait-based implementation providing an extract() method. Trait because there are u32 and u64 implementations of MT and they are different internally.</p><p>My screen manager (a struct) initially included the whole MT engine for internal use for random delays, random positions, etc. It worked perfectly.</p><p>But function pointers are a thing right? And I don't want the screen manager code to be dependent on my MT code - when all it needs is the function to provide a random u32.</p><p>So I could simply:<br>let mut fptr = mt.extract;</p><p>Doesn't work, more research... Needs a closure. Okay...</p><p>let mut fptr = || mt.extract();<br>// and call it like so<br>let randomnumber = fptr();</p><p>Cool - that works. Should be just as simple to attach that to the screen struct, right? Right?</p><p>No.... Not even remotely close.</p><p>Try to attach that function pointer to the screen struct. I dare you. (Just kidding, please don't.)</p><p>After some hair loss...and a few elapsed days thinking about the problem, and reading, reading.... Ok I give up, build a small test program.</p><p>jfc</p><p>The solution? In main program:<br>let mut mt = MersenneTwister::<u32>::new();<br>mt.seed(...) // my MT intentionally panics if unseeded and extract is called<br>let randfn = Box::new(move || mt.extract() );<br>let screen = Screen::init(... , randfn);</p><p>...and change the screen's struct and init code to accept that thing...</p><p>pub struct Screen {<br> ...<br> pub randfn: Box<dyn FnMut() -> u32>,<br> ...<br>}</p><p>impl Screen {<br> ...<br> pub fn init(... randfn: Box<dyn FnMut() -> u32> ) -> Screen {<br> let s = Screen::new();<br> ...<br> s.randfn = randfn;<br> s // return screen object<br> }<br> ...<br>}</p><p>That was hard, examples are few and far between. To be fair, I don't know what I should have searched for since the errors were all about lifetimes of the mt object, or a closure that is not a fn()->u32. No lifetime annotations are required to make this work now.... Unless you intend to build a setter function, in which case there is one lifetime required "+ 'static" ala:</p><p> pub fn setfunc(&mut self, func: impl FnMut() -> u32 + 'static ) {<br> self.randfn = Box::new(func);<br> }</p><p><a href="https://infosec.exchange/tags/rust" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>rust</span></a> <a href="https://infosec.exchange/tags/learning" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>learning</span></a> <a href="https://infosec.exchange/tags/AlwaysLearning" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>AlwaysLearning</span></a> <a href="https://infosec.exchange/tags/TryTryTryAgain" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>TryTryTryAgain</span></a></p>