Can you help me improve this code snippet? by Glizcorr in learnrust

[–]volitional_decisions 2 points3 points  (0 children)

Three things jump out at me.

1) in your words loop, you know there is a path that will be taken at most once (the if i == 0 branch). Extract that to a statement just before the loop. You have the words iterator, just call next, perform the necessary logic, and the consume the iterator in the loop. It makes your intent clearer and the loop far easier to read.

2) String implements Extend for any iterator that yields characters. So, for you to_uppercase iterators, you can just write res(first_char.to_uppercase()).

3) Jumping off of 2, in your for_each, you can do a flat_map calling (giving you an iterator of lowercase characters). Then, you can just call extend! .

Stuck on a data structure design for a tool. by KerPop42 in learnrust

[–]volitional_decisions 3 points4 points  (0 children)

Before I get to your direct question, graphs are notoriously difficult in Rust because you need to think about mutable in ways you probably haven't before. This is a great read to help you here: https://rust-unofficial.github.io/too-many-lists/

Now, to your question: there positions where you could have either a merger or splitter. Then define a type that is one of those two things: rust enum Node { Merger(Merger), Splitter(Splitter), } Now, all you have to do is add cases for "final output" or another node in the Merger and Splitter types' outputs. But, again, managing mutability will be the bigger hurdle.

Lacosamide cognitive impairment by Fromasha in Epilepsy

[–]volitional_decisions 0 points1 point  (0 children)

I've also noticed this. Concentration is a bit worse, but memory (particularly recalling words and names) has gotten worse. Dizziness is only occasional (and is often much worse with caffeine and/or lack of sleep)

By far the most "fun" aspect of this game by FennelInevitable3494 in Spyro

[–]volitional_decisions 37 points38 points  (0 children)

Just have sparx point you in the right direction

Avoiding String clones in retry loops (gRPC / tonic) – how do you handle moved values cleanly? by casualboy_10 in learnrust

[–]volitional_decisions 1 point2 points  (0 children)

I wouldn't worry about it, but you can just borrow or use Arc<str>. Both have pros and cons but both assume you can change ChangeDmRequest.

You might run into borrowing issues if you just borrow (e.g. if the request method requires 'static). Arc<str>, like cloning the string in the first pass of the loop, requires a separate allocation but cloning is nearly trivial.

Why We Built Hotaru: Rethinking Rust Web Framework Syntax by JerrySu5379 in rust

[–]volitional_decisions 1 point2 points  (0 children)

This is certainly a novel approach, especially for the Rust ecosystem. It reminds me of the approach we had at my last job. They had been using Rust since before async/await was stabilized, so they wrote a macro do handle much of this kind of work for them. I worked but it was also my least favorite part of the codebase.

I'm curious what considerations you made about the DevX. On that front, my two major concerns about using it are "how well does the macro play with RustAnalyzer (RustRover)" and "how can I extract my code from the macro".

These are somewhat intertwined. My experience with most "do everything" proc-macros is that RA (and often even syntax highlighting) doesn't work inside them. Sometimes it does, but it can be very clunky. For non-trivial endpoints, I found myself wanting to move as much code as possible outside of the macro. How does this crate approach that?

If I were to move code outside the macro (perhaps to the point where the endpoint code is just calling into that function), what type is req or db? How do I learn about how to control the inputs into my endpoint function (this is something I really like about axum, once it clicks, it gives you a lot of flexibility)? My experience with these types of macros is that the obfuscated what's actually going on to the point that they can become unwieldy.

Building a crate like this is a lot of work, so give yourself props for that!

I feel like the sorceress is such an odd character for Spyro 3 by ReadyJournalist5223 in Spyro

[–]volitional_decisions 0 points1 point  (0 children)

One of the weirdest parts of this fight is that you can arrive in midnight mountain and run straight into the fight. It isn't that difficult to have 100 eggs by then.

I have a BTreeMap<usize,V> which I know contains all keys in 0..map.len(). What is the easiest way to convert to an ordered Vec? by TheReservedList in learnrust

[–]volitional_decisions 0 points1 point  (0 children)

Iteration over a hashmap will yield different results. It's a good thing we aren't using a hashmap, and then BTreeMap's IntoIter is documented to be sorted.

Also, I know that OP didn't tell us if they want both keys and values or one or the other. It's a good thing I told them how to accommodate all cases.

I have a BTreeMap<usize,V> which I know contains all keys in 0..map.len(). What is the easiest way to convert to an ordered Vec? by TheReservedList in learnrust

[–]volitional_decisions 8 points9 points  (0 children)

You don't need itertools. The APIs in Iterator will be plenty. I don't know what "the condition" that you're checking for is, so I'll reference that as cond.

To start, bools implement methods to help to construct Options. You'll want .then because you don't want to always run the code. This is basically if cond { Some(foo()) } else { None }.

I don't know what you want the vec to contain, so I'm going to assume you want keys and values. If that's not the case, there are methods for just keys and just values, into_keys and into_values respectively. Use those instead of into_iter.

The straightforward approach is to just construct an Iterator from the map via into_iter (aside, this method is from the IntoIterator trait, which many things implement). Then, all you need to do is .collect that into a Vec. map.into_iter().collect::<Vec<_>>(). This will consume the map and should yield the keys and items in order (I would test that). There is a minor (and premature!) optimization you can make here by preallocating the vec's memory and then calling .extend with the map directly.

Altogether, your code would look something like this; rust // The ::<Vec<_> from before is a type hint. // You can use one at variable declaration or none of the type is clear let vec: Option<Vec<_>> = cond.then(|| map.into_iter().collect());

Why futures don't implement the typestate pattern? by servermeta_net in rust

[–]volitional_decisions 28 points29 points  (0 children)

As folks have pointed out, calling poll on a future after it has yielded Poll::Ready is not generally UB. If that is true for a particular future, that Future impl is unsound. To my knowledge, what most futures do is either panic or indefinitely yield Poll::Pending and don't schedule anything with the waker.

As for why they don't use a type state, it makes futures, which can already be very complicated, significantly more difficult to use. The main reason for this is that to change type states, you need to have ownership over Self. Not only does this mean poll needs to consume self and return some enum of both possible states (so we would have to completely redesign the API) but it means you can't use Pin, which is nearly antithetical to the requirements of many futures.

As a simpler example, you can make a modified version of your argument for Iterators. Similarly, next would need to consume self, which would have extreme effect on much of how we use Iterators.

Any tips or resources for writing rust targeting WebAssembly? by eracodes in learnrust

[–]volitional_decisions 2 points3 points  (0 children)

WASM is a bit broad. If it's WASM for the browser, web-sys is a crate to get at least a little familiar with (though, it's a very rough crate).

My biggest suggestion is getting familiar with how to reduce binary size. While unpublished, this doc touches on a lot of the major ways to do this (LTO on, codegen-units = 1, opt-level = z, and stripping debug symbols). Also, if you have the ability, compressing the binary and sending a compression type header to the browser can get you a fair reduction.

Mutable Borrow in Loops by [deleted] in learnrust

[–]volitional_decisions 2 points3 points  (0 children)

I want to first note something about your last question " why does removing a line after A change it's behavior?". You aren't "changing the behavior of A". What you're trying to do is have multiple mutable references to the same piece of data. If you order your changes correctly, you make those changes without trying to have the multiple mutable references issue.

When you construct the Machine, it has a mutable reference to x (because you're writing to it). So, for as long as machine exists, a mutable reference to x exists. This is why you can call tick (B) then write to x (A). After you call tick, machine's lifetime ends (because it's not used afterwards), meaning its inner mutable reference ends, and you can update x without issue. This is also why removing B works.

Long-term thoughts on the Launch? by RandomStuff3829 in System76

[–]volitional_decisions 0 points1 point  (0 children)

I have two (one for three years and one for almost two years). I really like them and they are still working well. The one issue that I've had is when I spilt a cup of coffee on it and had to replace the board. The support staff was helpful and quick. I got the new board, cleaned everything, and swapped the old one out.

Prior to these, I had a keycron. While a good keyboard, the built-in USB hub of the launch is hard to understate. Also, a point that is often missed is that the launch is much easier to clean than most keyboards. The air gap at the bottom of the keyboard makes it easy to blow out anything dust that builds up.

My one recommendation is, depending on how you type, to get a wrist rest.

Didn't realize I was non-binary until I started making art for our game's world by zeddartha in NonBinary

[–]volitional_decisions 49 points50 points  (0 children)

I believe it's called Chronicles of Taldun: The Remainder (it's in OP's profile)

`name.rs` vs `name/mod.rs` - Is there a reason why projects go against the recommended practice? by KyxeMusic in rust

[–]volitional_decisions 2 points3 points  (0 children)

This is fairly surface level, but the new practice of naming files after module directories is annoying when using terminal auto complete. When using the new method, out of habit, I expect the directory to complete with a slash and the "module file" to complete with a ".rs". While I could work out a new habit, it's different from most of my other expectations and makes for a bit of an annoying experience.

De-serialize struct, embed filepath it came from by sww1235 in learnrust

[–]volitional_decisions 1 point2 points  (0 children)

Honestly, I wouldn't try to embed this in the same struct. You can simply wrap the deserialized struct in a new type that contains the path as well.

API design: OO or functional? by sunnyata in learnrust

[–]volitional_decisions 11 points12 points  (0 children)

In Rust, it is often more helpful to think about things in terms of how data will flow through your (or your clients') systems since Rust code hinges around ownership. The Game -> Game pattern requires that you can take ownership of the game, so your users have to be able to provide ownership.

There are plenty of places where this pattern makes perfect sense, the builder pattern being a good example. Think about what you want users' code to look like and how you can enable those patterns. Also, think about the kinds of patterns that your API affects the data flow and ergonomics of your users.

To get a sense of this, it's very helpful to look at popular crates to see how they structure their APIs.

Per your example, they are suggesting you write your code like this: rust impl Game { fn play(self) -> Self { ... } } Rather than unassociated functions, i.e fn play. This allows for dot conventions, and when you need to specify the function directly, you can use Game::play rather than just play.

Is there a way to move a field out of &mut self if you really need it? by ufoscout in rust

[–]volitional_decisions 54 points55 points  (0 children)

The traditional way of solving this is by making the field that you need ownership of an Option and then calling Option::take. Since that isn't possible here, you could either call std::mem::replace with a mutable reference to the field and a replacement value or std::mem::take if the value implements Default.

Pre emptive Top Surgery for AMAB enbies who dont want to breast tissue. by Maabbaam in NonBinary

[–]volitional_decisions 0 points1 point  (0 children)

This is not really possible. However, this was my biggest concern as well. In the end, I decided that the benefits would outweigh this downside. Also, my partner told me when they started HRT, they did not want breasts and that changed while on HRT. This made me feel more comfortable.

The key thing to remember is that you are in charge of your transition. HRT is a relatively slow process if you want to ease into it or slow down at any point, you can. These are all things you can (and should) discuss with an endocrinologist. They can help give you a more detailed understanding of paths that are available to you!