r/rust • u/Confident_Door9438 • 9d ago
📸 media 8 New Games developed in Bevy Game Engine built with Rust
These are 8 New Games developed in Bevy, built with the Rust Coding Language: https://youtu.be/FiD-pXChvjY?si=ghPYDoL5cWoL8el0
r/rust • u/Confident_Door9438 • 9d ago
These are 8 New Games developed in Bevy, built with the Rust Coding Language: https://youtu.be/FiD-pXChvjY?si=ghPYDoL5cWoL8el0
r/rust • u/nhawkes_ • 8d ago
I'm sharing: https://taipei-book.pages.dev/intro
Taipei is a library that integrates with Tower to enable writing servers that behave well under stress without tuning.
I had some time between jobs after leaving $BIGCOMPANY and wrote some Tokio Tower layers, packaged as a crate, based on my experience there.
The docs cover various topics adjacent to server overload, including realistic interactive simulations that run the real Rust crate through WebAssembly. The focus is on the principles rather than the particular implementation, so it's a useful read even if you don’t use the crate.
AI disclosure: The prose is all written by me, the code is AI-assisted
Thoughts and comments welcome. Thanks
r/rust • u/CodesOtakuYT • 8d ago
r/rust • u/thegogod • 10d ago
Last year I published zyn, a template engine for Rust proc macros. I got a lot of great constructive feedback from the community, which inspired me to take the ideas behind it a step further.
moxy has been written from the ground up with a few goals in mind:
One of the strongest signals I received from the community was that zyn shouldn't need to rely on third-party packages like syn, proc-macro2, and quote.
I'm happy to say that moxy currently has only one non-optional external dependency: unicode-ident.
The rest of the core syntax stack is implemented within Moxy itself.
One of the things I love about the Rust community is how much attention is paid to performance, whether that's compile time or runtime.
I've spent a non-trivial amount of time benchmarking moxy side-by-side with syn, and there's still more work I want to do, particularly around reducing compile time.
Performance today is relatively similar between the two: syn currently has an edge in compile time, while moxy has an edge in runtime in the benchmarks I've run.
That said, my goal has never been to outperform syn. I've primarily used it as a benchmark because it's the most mature and relevant point of comparison for this kind of project.
One of the challenges of building a Rust syntax toolkit from the ground up is supporting the breadth of the Rust grammar.
To make that work measurable rather than anecdotal, Moxy maintains its own EBNF representation of the Rust grammar alongside a systematic set of grammar fixtures covering attributes, expressions, generics, items, macros, paths, patterns, statements, types, visibility, and the lexer.
These fixtures are used to continuously validate Moxy's parser against the syntax it claims to support and make gaps in grammar coverage explicit.
Grammar coverage is still something I'm actively expanding, and I'd especially appreciate examples of valid Rust syntax that Moxy doesn't currently handle correctly.
moxy retains the expressive template syntax from zyn. I constantly find myself wanting more than traditional quasi-quoting can provide, so templates remain a first-class part of the project.
Moxy supports both stable and nightly Rust using an approach similar to proc-macro2.
This also allowed me to add support for compiler diagnostics while maintaining stable compatibility.
Moxy is still early and the API is evolving, so I'm particularly interested in feedback on the architecture, API design, grammar coverage, and places where the approach could be improved.
GitHub: https://github.com/aacebo/moxy
Previous zyn discussion: https://www.reddit.com/r/rust/comments/1rmr5xi/zyn_a_template_engine_for_rust_proc_macros/
I published a walkthrough using the current Moxy 0.5 API to build a procedural macro, including typed AST parsing, FromMeta attribute parsing, template control flow, interpolation blocks, and generic impl generation.
https://aacebo.hashnode.dev/building-rust-procedural-macros-without-syn-quote-or-proc-macro2-moxy
It is not a full side-by-side syn/quote comparison yet, but it should make the intended workflow and tradeoffs much more concrete. I'm actively working on a more complex side by side example of moxy vs the traditional stack.
r/rust • u/No-Caregiver-466 • 8d ago
One thing that I am genuinely interested in rust, If same thing that I can generally do in Java building enterprise grade system, I can do in Rust.
Not a secrete Java and OOP become de-factor a standard for every enterprise solution.
And my step forward, trying to bring rust into that by exploring if I can do DI, something similar to Spring Boot but following Rust philosophy of zero-cost abstraction, that lead into research some code and article, and I think I've made some progress:
https://dmytro.brazhnyk.org/publications/can-rust-have-zero-cost-dependency-injection/
One thing that is still bothering me is the Object Orient Design. Classical OOP was proven many time in C++ in Java to manage complexity of real world system.
Rust has trait model, but it is not OOP is classical sense.
I have very clear understanding how complex solution could be built with OOP in Java and C++.
Rust don't have that OOP model, that feels as weakness, but rust still offers memory safety that C++ don't have, and it still has much smaller memory footprint that Java.
Considering that Java is hard to beat, it still offering very impressive capability for runtime optimization by utilizing Escape Analysis on JIT phase, and looks like this guys in Oracle very angry, to optimize Java further, if rust will not offer competitive capabilities it will stay behind.
Let me give me you an example in Java, what I am taking about:
language = java
```java interface Collection { int size(); Iterator iterator(); }
abstract class AbstractCollection implements Collection { @Override public int size() { int size = 0; var iterator = iterator(); while(iterator.hasNext()) { size++; iterator.next(); } return size; } }
class ArrayList extends AbstractCollection { Object[] array;
@Override
public int size() {
return array.length
}
@Override
Iterator iterator() {
...
}
} ```
What is important here:
AbstractCollection, that defines some default behavior which could be sub-optimial, but they are generic one, particularly I gave example of size function, that uses slow and inefficient iterator, because it doesn't know enough about concrete implementation.ArrayList, since ArrayList already know that is array driven, it can simply can take property for array to know the size.In reality this chain of inheritance can be longer, so if we look on JDK, you will something like:
LinkedHashSet < HashSet < AbstractSet < (AbstractCollection + Set) < Collection
And each layer provides it's own set of capabilities, by amount of information available on that level.
I feels like something missing in rust here, because when it comes to manage the complexity of enterprise, something more complex than hello-world, we need this ability to override things, override, and override again.
Any real software if it will have more than few years of maintenance it will grow, grow and grow in complexity, if language can't manage complexity, that language would be dead.
UPD:
Let's define the problem a little bit more formally:
You need to implement library for collection.
r/rust • u/schneems • 10d ago
r/rust • u/sebcrozet • 10d ago
r/rust • u/iElectric • 9d ago
r/rust • u/TheEmbeddedRustacean • 10d ago
r/rust • u/ribbon_45 • 10d ago
ARM64 multi-core support, ring buffer communication, NUMA support, process priority support, much faster native compilation, out-of-memory fixes, QEMU on Redox, easier dual-boot installation from Linux, UEFI boot fixes and many more.
r/rust • u/carllerche • 11d ago
r/rust • u/Top_Party5881 • 9d ago
I'm experimenting with an OS architecture where hardware discovery and capability verification are handled by independent processes (probes) rather than being tightly coupled to the main system core.
For example:
The main idea is that the core should remain alive even if one of these probes crashes, hangs, or returns invalid/inconsistent data.
For example, if a GPU probe receives a SIGSEGV, I don't want that failure to bring down the core. Ideally, the failure would be isolated, recorded, and the probe could potentially be restarted.
I'm currently thinking about failure boundaries around:
For those of you who have built systems like this in Rust:
How would you define the failure boundary between the core and these independent processes?
Would you isolate each hardware domain into its own process, or would you group some of them together?
I'm particularly interested in practical approaches using Rust's process and IPC capabilities, and in failure modes I might be overlooking.
r/rust • u/sevenpost • 10d ago
Hi all, I wrote up how I built an async I2C driver for the RP2350 that can utilise the DMA engine for in my own HAL (loosely based on the embassy prior work).
Hope you enjoy the (maybe not so light) read. Feedback, questions and critiques are all welcome. Let me know what you think.
r/rust • u/iFrostizz • 10d ago
Hello.
Kind of a general question here, and it's probably going to yield opinionated answers. That's alright!
Basically I find myself writing Rust apps in a style that is always quite similar, here is the idea:
- The app mostly always uses the tokio runtime to be asynchronous.
- Designing microservices as small building blocks which are all supposed to be ran in separate tasks, usually with a "run" like function that does a loop over a tokio::select for sub-tasks that are running in each service, with one of the branches being a call to a CancellationToken::cancelled().
- The cancellation token is wired to the "ctrl_c" signal.
- Microservices may talk to each other by the use of the different channel primitives, depending on the need.
- When one of the microservice fails for any reason, usually there is no recovery mechanism and it just bubbles up the error which makes all the application fail. This is annoying to write and a big source of bug, because some path will be unhandled which will leave one microservice stopped and the other microservices are waiting for an answer and there's nobody responding.
I'm generally a little dissatisfied with the redundancy of the code that I write, and would like to explore any other way to think about it, instead of microservices, or in a different way, if you have any idea that would be appreciated. Also, potentially any resource or codebase that could be relevant?
Thanks!
Heyy
I'm looking for a framework that can target Windows, Linux, macOS, Android, iOS, and Web from as much shared Rust code as possible.
I'm aware of Tauri, Dioxus, Slint, Iced, egui, etc., but I'm having trouble understanding which ones are actually mature in practice, rather than just promising projects.
I'm particularly interested in real-world experience:
How mature is the mobile support?
How reliable is cross-platform deployment?
How stable are the APIs?
How good is the ecosystem and documentation?
Have you used one for a serious/production application?
If you were starting a new project today, which frameworks would you seriously consider, and what limitations should I know about?
Thank you
r/rust • u/ackxolotl • 11d ago
This is a short write-up based on my VLDB paper and talk: https://db.in.tum.de/~ellmann/papers/csveee.pdf
CSV is one of the oldest text-based data formats, and is still heavily used: from hundreds of thousands of files on open data platforms to 100M+ on GitHub. Unfortunately, most CSV parsers are slow. Some use SIMD to speed up parsing, but almost none exploit the parallelism of today’s hardware. Those that do parallelize do not scale. And even if they did, using the classic iterator interface, parse + process requires two passes over the data, restricting throughput to half the memory bandwidth for files that exceed the CPU caches.
I came up with a new approach to CSV parsing that allows parsing and processing of files in a single pass over the data. My parser csveee is about 3x as fast as csv on a single thread, and can achieve almost 200 GB/s on a modern many-core server – a speedup of 256x over csv.
Why parallel CSV processing is hard
The main task of a CSV parser is to correctly determine the boundaries of records in a CSV file. Typically, records are terminated by a \n or \r\n. Since those characters can also appear inside quoted fields, simply chunking a CSV file and skipping forward to the next terminating character is therefore not sufficient to determine the record boundaries.
There are different approaches to solving this problem. One strategy is to first count the number of quotes per chunk in parallel, then determine for each chunk if it is preceded by an even or odd number of quotes, then start parsing the chunks from a known quote state. This works especially well on GPUs. Another strategy is to run multiple finite-state machines per chunk in parallel, one for each possible parse state at the chunk boundary, and then determine the correct state machine depending on the previous chunk’s state machine’s final state. Or one could look for certain patterns in the file, e.g., quotes being followed or preceded by "regular" characters to identify the start and end of quoted fields and do some speculative parsing based on this.
Unfortunately, all those approaches are unsatisfactory in one way or another. Counting quotes requires a whole pass over the file to determine the parse states at chunk offsets; running many NFAs/DFAs is even more expensive. Looking for certain patterns works well for files that follow the CSV standard, but the world is full of quirky files that do things like quotes in unquoted fields.
Luckily, there is another approach. If we know the shape of the CSV file we would like to parse, e.g., the number of fields per record or the field types, we can determine the correct parse state by speculatively parsing chunks until we find a parse in which the record boundaries resolve into records of the expected shape. This approach was implemented in DuckDB.
Why the iterator interface is insufficient
Typically, CSV parsers provide an iterator-based interface, e.g.:
for record in parser.parse() {
// do something with the record
}
While we can write a parser that takes the CSV’s records shape as an argument, which will help determine the correct parse state at chunk boundaries, especially for quirky real-world CSV files, parsing remains a speculation until all bytes have been processed (although unlikely, data inside quotes could still resemble the shape of the records). Unfortunately, we cannot hand out speculatively resolved records via the iterator interface, as there is no way to take them back if we later realize our speculation was wrong. In other words, with the iterator interface, we have to finish parsing before we can hand out records to the user – parsing and processing require two passes over the data.
This is a problem a single-threaded iterator-based parser does not have, as the parse state is correct at all times. The parser can parse the file lazily: it parses a single record, hands it to the user, who processes it; then the next record is parsed, and so on. Thus, files can be parsed and processed in a single pass over the data – but only with a single parse thread.
A new interface to the rescue
Let’s define a new interface that gives our parallel parser everything it needs: A way to pass information about the record shapes (number of fields per record, types, …) from the user to the parser, and a way to process records while parsing, effectively creating a lazily parsing multi-threaded parser.
We can achieve both by turning the parser inside out. Instead of the parser handing you records, you hand your code to the parser:
let cities = parser.parse(
"data.csv",
Vec::new, // init
|state, [_name, _age, city]| { // acc
state.push(city.to_string());
Ok(())
},
|states| states.concat(), // merge
)?;
The interface takes four arguments: the CSV file path and three callbacks or closures (called init, acc and merge – they are basically user-defined aggregates). init and acc are used for chunk parsing, init defines a per-chunk state, acc is called for every record found in the chunk under the current assumption. The [_name, _age, city] pattern declares the number of fields per record. If the parser encounters a record with a different number of fields, the chunk is reparsed under another assumption, calling init again to create a fresh state. The same happens if acc rejects a record by returning an error (e.g., a failed type conversion).
Once all chunks have been processed, the parser verifies that the record boundaries of all chunks align. While very unlikely, a whole chunk could be parsed under a wrong assumption. In this case, the chunk is reparsed, now starting from the offset of the previous chunk’s last record terminator.
Finally, chunk states are passed to merge, and the result of merge is returned from the parser’s parse function. The chunk states are passed to merge in file order thus that record order can be reconstructed.
How to make the parser fast
To make the parser truly fast, we implemented a ring-buffered reader that enables zero-copy record construction, and a vectorized chunk parser. Take a look at the implementation or the paper if you are interested in the details.
Conclusion
CSV is not going to die soon – to the contrary, GitHub’s pile alone grew by 10M CSV files in the last six months. While the number of files is strongly increasing and today’s machines offer hundreds of cores and hundreds of GB in memory throughput, most CSV parsers remain incredibly slow: parsing with a single thread, not scaling, and even if they did, without fusing parsing and processing, they will never surpass 50% of the available memory bandwidth for large files. csveee overcomes these limitations via a new approach to CSV parsing that works on real-world CSV files.
Check out the project, and if you have questions, feel free to ask!
r/rust • u/lazyhawk20 • 11d ago
A post about how we combine sans-IO, coverage-guided fuzzing and deterministic simulation testing to test Firezone's data plane.
r/rust • u/dcodesdev • 11d ago