r/rust
TIL that print!(…) is not the same as write!(stdout(), …).unwrap()
While doing some work with io redirection, I learned something surprising about how the standard streams work: print!(…) is not equivalent to write!(io::stdout(), …).unwrap(). The key difference is output capture: when running tests, cargo / rust advertise the ability to capture stdout and stderr and present it only on test failures (togglable with --no-capture); as it turns out, this only works when using the standard printing macros and does not apply to direct writes to the stdout() object. Same thing applies to println!, eprint!, etc. This discrepancy isn’t mentioned at all in the docs for the formatting macros or standard streams, and the relevant docs in cargo describe only that “stdout and stderr can be captured”.
Rust Glancer: a memory-efficient Rust language server
rust-glancer.github.ioOfficial /r/rust "Who's Hiring" thread for job-seekers and job-offerers [Rust 1.98]
Welcome once again to the official r/rust Who's Hiring thread!
Before we begin, job-seekers should also remember to peruse the prior thread (note: the link is correct; I missed 1.97, whoops).
This thread will be periodically stickied to the top of r/rust for improved visibility.
You can also find it again via the "Latest Megathreads" list, which is a dropdown at the top of the page on new Reddit, and a section in the sidebar under "Useful Links" on old Reddit.
The thread will be refreshed and posted anew when the next version of Rust releases in six weeks.
Please adhere to the following rules when posting: Rules for individuals:
Don't create top-level comments; those are for employers.
Feel free to reply to top-level comments with on-topic questions.
Anyone seeking work should reply to my stickied top-level comment.
Meta-discussion should be reserved for the distinguished comment at the very bottom.
Rules for employers:
The ordering of fields in the template has been revised to make postings easier to read. If you are reusing a previous posting, please update the ordering as shown below.
Remote positions: see bolded text for new requirement.
To find individuals seeking work, see the replies to the stickied top-level comment; you will need to click the "more comments" link at the bottom of the top-level comment in order to make these replies visible.
To make a top-level comment you must be hiring directly; no third-party recruiters.
One top-level comment per employer. If you have multiple job openings, please consolidate their descriptions or mention them in replies to your own top-level comment.
Proofread your comment after posting it and edit it if necessary to correct mistakes.
To share the space fairly with other postings and keep the thread pleasant to browse, we ask that you try to limit your posting to either 50 lines or 500 words, whichever comes first.
We reserve the right to remove egregiously long postings. However, this only applies to the content of this thread; you can link to a job page elsewhere with more detail if you like.Please base your comment on the following template:
COMPANY: [Company name; optionally link to your company's website or careers page.]
TYPE: [Full time, part time, internship, contract, etc.]
LOCATION: [Where are your office or offices located? If your workplace language isn't English-speaking, please specify it.]
REMOTE: [Do you offer the option of working remotely? Please state clearly if remote work is restricted to certain regions or time zones, or if availability within a certain time of day is expected or required.]
VISA: [Does your company sponsor visas?]
DESCRIPTION: [What does your company do, and what are you using Rust for? How much experience are you seeking and what seniority levels are you hiring for? The more details the better.]
ESTIMATED COMPENSATION: [Be courteous to your potential future colleagues by attempting to provide at least a rough expectation of wages/salary.
If you are listing several positions in the "Description" field above, then feel free to include this information inline above, and put "See above" in this field.
If compensation is negotiable, please attempt to provide at least a base estimate from which to begin negotiations. If compensation is highly variable, then feel free to provide a range.
If compensation is expected to be offset by other benefits, then please include that information here as well. If you don't have firm numbers but do have relative expectations of candidate expertise (e.g. entry-level, senior), then you may include that here.
If you truly have no information, then put "Uncertain" here.
Note that many jurisdictions (including several U.S. states) require salary ranges on job postings by law.
If your company is based in one of these locations or you plan to hire employees who reside in any of these locations, you are likely subject to these laws.
Other jurisdictions may require salary information to be available upon request or be provided after the first interview.
To avoid issues, we recommend all postings provide salary information.
You must state clearly in your posting if you are planning to compensate employees partially or fully in something other than fiat currency (e.g. cryptocurrency, stock options, equity, etc).
Do not put just "Uncertain" in this case as the default assumption is that the compensation will be 100% fiat. Postings that fail to comply with this addendum will be removed. Thank you.]
CONTACT: [How can someone get in touch with you?]
ssh late.sh - the Clubhouse now has live streaming, synthwave radio, NetHack, DCSS, Brogue, and a whole BBS door games wing :)
Three months since my last post here, and honestly I don't know how to fit everything in. Let's try :)
Biggest news is that we got featured by Orhun, the creator of ratatui! For an app that is 100% ratatui, that one felt like a knighthood :D
For the newcomers, late.sh is a clubhouse inside the terminal. A place to take a break, chat with people around the globe, listen to music, play a game, water your bonsai.
ssh late.sh
That's it :) No passwords, no OAuth, no accounts. Your SSH key is your identity. And the whole thing is Rust, from the russh server down to the last door game host.
The roguelikes
- Dungeon Crawl Stone Soup, the real console crawl running over SSH, your save persists, and our server files are published for dcss-stats/Sequell.
- NetHack, the one hanging in MoMA. Real upstream binary, your save persists, the dead stay down there, and your bones haunt other late.sh players.
- Brogue CE, arguably the most beautiful ASCII ever put on a terminal, full truecolor over SSH.
And here's the fun part, ascensions, orb runs, and escapes now pay chips and permanent profile badges, counted from the hosts' log files, all rolled into a big Leaderboards page.
The BBS door games wing
- Legend of the Green Dragon, the classic LORD, rebuilt native in Rust. Hunt the forest, beat your master, slay the dragon.
- A Dark Room, a native port of the incremental classic, and unlike the browser one, ours has a real ending. Win the ascent and it pays 10,000 chips, burns your save, and the next visit starts from a dead fire.
- Usurper, the actual LORD-era door from the 90s, resurrected on a PTY, one shared persistent world.
- BashQuest, our own original, a door game that teaches Linux/Bash, with tamper-resistant graduation certificates.
- dopewars, CodeKeep, Rebels in the Sky... buy low sell high, defend the Pale, play space-pirate basketball.
Lateania
Our persistent multiplayer text-world deserves its own section now, because it quietly became a full MUD. ~10,000 rooms across five continents, an overhead world map with fog of war, seventeen classes, mounts, an open zone where players can duel each other, animal taming (55 beasts, each with their own skills), fishing (40 species), trade skills that chain, player housing, and four endgame crowns that each pay 10,000 chips. It gets updates weekly and I can't stop the contributors, nor do I want to :D
The Lobby
- Ctrl+G anywhere, every multiplayer game in one list.
- eight correspondence games, chess, chess960, battleship, connect four, reversi, checkers, backgammon, and briscola (our first hidden-hand card game). Post a challenge, walk away, one move per day whenever you're around. Every match gets its own private chat + voice room for proper trash talk.
- five always-on house tables, poker, blackjack, tron, super snake, asterion
MUSIC
- the radio, the new shit :) Live synthwave from Nightride FM, with their blessing and live artist/title attribution. Five stations, Chillsynth, Nightride, Datawave, Spacesynth, Ambient. This is what late.sh sounds like now.
- the booth, a community YouTube jukebox. Queue tracks, vote, skip, browse the history of everything that ever played. Someone's always DJ-ing.
- the library, 600+ curated CC0/CC-BY tracks (lofi, ambient, classical), all controlled from inside the TUI.
STREAMING. In your terminal. Yes, really :D
/golive and you're broadcasting your screen to an unlisted watch page, straight from the browser or from OBS (we mint a WHIP ingress, you paste a URL + token into OBS and go). Your friends get notified, viewers get a watch page with volume and fullscreen, CLI folks in the room talk over voice chat, and you moderate your own stream room. Watch links are unguessable capability URLs that die when the stream ends.
The AI translator
Chat is global, so now it translates itself. Press t on any message, or turn on auto-translate and every new message in the room arrives in your language. Translations are cached and shared, so one API call serves every reader. People who don't share a language are having actual conversations now, and honestly, it feels a bit magical.
Ok, and one for the rustaceans :)
The rule behind streaming + voice, late-ssh never touches a media byte. `VoiceService` is just an in-memory control plane that mints LiveKit JWTs, the native `late` CLI does the actual mic capture and playback through LiveKit's Rust SDK, and the TUI only sends join/mute over a WebSocket and renders the roster from a `watch` channel. Media never gets near the SSH render loop (it literally can't, WebRTC goes straight to LiveKit)..
A stream is not a second system, it's one extra video track published into the room's existing LiveKit voice room. /golive registers in an in-process registry (one stream per user, Pending -> Live -> Grace) and hands out capability URLs, 122 random bits in 22 characters. Unguessable IS the access model, no accounts on the watch page, and the publish link is claim-once, first browser to grab it owns it, a leaked link just 403s. The share publishes under a hard 1.5 Mbps cap, because the SFU re-sends the publisher's bitrate once per viewer, so that cap IS the whole fan-out cost. OBS works too, we mint a WHIP ingress and poll it, same state machine either way, and the "went live" line in chat only fires on the first real media report, never at a black screen.
Still a team effort, still a great vibe. Hop in, take a break ;)
License: FSL-1.1-MIT
Code: https://github.com/mpiorowski/late-sh
Landing: https://late.sh
arrayref v0.3.10 compromised
Version v0.3.10 released hour ago. Have dependency proc-macro1 published by `dtolney` (typo squatted name).
People using Cedar policies, how are you managing them?
I'm exploring policy languages for authorization in my application. I took a look at Cedar, and it seems like a good fit because it written in Rust and has first class support for the language, but programatically creating and managing policies seems awkward. This has been a stumbling block for me and I'm curious how people are using cedar policies.
Most of the documentation provides examples of policies that are written out in human readable formats, like this
permit(
principal == User::"alice",
action == Action::"update",
resource == Photo::"VacationPhoto94.jpg"
);
These examples make sense if users are writing your policies and managing a text file of policies. But in most system's I've built, the nobody is writing out authorization policies in text. Usually you have a UI over your authorization core and your users are adding and removing permissions for users and groups of users via the UI. In this situation the text based policy approach becomes awkward and it seems like the preferred (only?) API for policy creation and management.
Looking at the examples, it doesn't seem like there is a "native" alternative to string based approach. The official tindytodo example has code like this:
lazy_static! {
pub static ref APPLICATION_TINY_TODO: EntityUid = r#"Application::"TinyTodo""#.parse().unwrap();
static ref ACTION_EDIT_SHARE: EntityUid = r#"Action::"EditShare""#.parse().unwrap();
static ref ACTION_UPDATE_TASK: EntityUid = r#"Action::"UpdateTask""#.parse().unwrap();
static ref ACTION_CREATE_TASK: EntityUid = r#"Action::"CreateTask""#.parse().unwrap();
static ref ACTION_DELETE_TASK: EntityUid = r#"Action::"DeleteTask""#.parse().unwrap();
static ref ACTION_GET_LISTS: EntityUid = r#"Action::"GetLists""#.parse().unwrap();
static ref ACTION_GET_LIST: EntityUid = r#"Action::"GetList""#.parse().unwrap();
static ref ACTION_CREATE_LIST: EntityUid = r#"Action::"CreateList""#.parse().unwrap();
static ref ACTION_UPDATE_LIST: EntityUid = r#"Action::"UpdateList""#.parse().unwrap();
static ref ACTION_DELETE_LIST: EntityUid = r#"Action::"DeleteList""#.parse().unwrap();
}
It seems like suggested way of creating policies is by constructing policy strings, it doesn't seem like there is a Rust "native" API. In my own attempts at using cedar I've ended up doing something similar to what you see in the examples, using strings to define my actors, actions, and entities. This doesn't feel right.
And then when policies are created, its not clear how you should manage them. The docs indicate you could have users x objects policies:
> For example, if you have 10 users and 10 resource types, that could mean 100 policies. This is expected and correct
If a Alice removes Bob's access to one of her documents, how should the application find this policy in the pile of json/string policies? In practice this has involved iterating every single policy, with a lot of string parsing and string equality checks, which feels wrong in Rust.
The way cedar expects you to use it does not feel idiomatic. It feels like there is a missing layer/library over cedar policies for programmatic usage, eg one where your actions are enums, but I don't know if I am "holding it wrong".
ouma - a hardened Linux libc written entirely in Rust
Hi everyone! I've been writing a libc for my GNU/Linux distro that focuses on being secure, correct and safe.
I try to minimize the usage of unsafe keywords to raw pointer referencing, slice creation from raw pointers, variadic argument manipulation and inline assembly.
For now my libc has a working locale, fast string to number conversion and vice versa, working printf and multibyte conversion functions.
There are still bugs and the project is early in development, though they are being caught.
Unlike redox's relibc, ouma is written entirely in rust with some bits of assembly (yes, even strtold returns valid long double values according to the architecture abi on Linux).
Aside from writing the entire libc in a memory safe language I also want to support modern compiler mitigations that require libc support such as shadow call stack, Intel CET, cross DSO cfi aka CFI for dynamic libraries.
Anyway, the links to the project are here:
GitHub: https://github.com/rseclinux/ouma
Codeberg: https://codeberg.org/gnu2/ouma
If you are willing to contact me, you can mail me at: theexanori@gmail.com
edit: I've made ouma specifically to force people to open source their entire projects if they are willing to use it. I do NOT state it as musl alternative in terms of being corporate/commercial friendly libc implementation. I want users of my libc and other projects to be sure that their software that is linked against ouma is free as freedom, does not hide anything behind the scenes because I personally believe that with transparency comes the security and by extension privacy as well. There might be issue with lgplv2 projects but I think I will write a linking exception for them
Zellij 0.45: Kitty Graphics support, Nested Sessions, Scroll by Command, new Rust APIs
Hey Rustaceans,
I'm excited to share that we just released version 0.45 of Zellij, the Rusty terminal workspace and multiplexer. This version includes some long-requested features as well as some fun new stuff you can do with Rust plugins. Highlights:
- Support for the Kitty Graphics Protocol for displaying images in the terminal
- Native support for Nested sessions (eg. opening Zellij-inside-Zellij over SSH)
- Scroll by Command and not just by lines
- New UI
- Rust APIs now allow us to: read other pane's screens (can be useful to do stuff like notify on silence), open background panes without stealing focus, control the new mobile UI. There's been lots of activity in the plugin ecosystem and I'm looking forward to seeing what you come up with.
Check out the full blog post: https://zellij.dev/news/nested-sessions-kitty-graphics-new-ui/
Or grab the release directly: https://github.com/zellij-org/zellij/releases/tag/v0.45.0
Happy hacking!
Curious with crates
Fairly new with rust and currently having fun learning the language. I was just wondering on how do you find crates or how do you know what crates to use on your project is there some holy grail or atleast a required sets of crates for your projects?
My goal in mind right now is to learn rust by creating some CLI tools that will help me with my day to day workloads.
I’ve been working on Tabularis, an open-source desktop database client for Postgres, MySQL and SQLite.
It’s meant to be two things at once: a comfortable everyday SQL app (editor, notebooks, charts, visual tools) and a safe bridge for AI agents that want to read your schema or run queries, without you having to paste credentials into a chat.
Free, open source, runs locally. Would love your thoughts.
Investigating why RustCrypto is slow: Deep dive into Rust SIMD programming
kerkour.comAnnouncing the Code-Infrastructure-as-Code (CIaC) compiler: one source file, five language targets, whole-system simulation, no (required) infrastructure
Hi rustaceans,
I recently designed the Code-Infrastructure-as-Code (CIaC) compiler, a command-line development tool (written predominantly in Rust) for a declarative DSL that can describe an entire service system in at least one file.
CIaC treats .ciac files as the architectural source of truth and compiles into Rust, Python, TypeScript, Go, and/or Java. Real deployment artifacts can also be generated: compose, Kubernetes, Terraform, or CI.
All that you're expected to do is declare the system specifications and the compiler handles the rest. External handlers are seeded once for injecting your own code and never overwritten, whereas inline handler bodies, such as the ones in the examples below, are compiler-owned and regenerated every build.
Why does this exist?
Put simply: to increase backend development speed and service reliability for both humans and agents.
As for myself: I initially created this tool for my own usage, as I spend a lot of time experimenting with infrastructure and building out services to serve domain-specific requirements. In other words, I got tired of building and maintaining services myself so I concocted a solution.
A technical perspective
A .ciac file describes a system as a set of declarations consisting of records, APIs, pipelines, streams, and workers.
Here's a single service example (event-pipeline):
// A single-service event pipeline
//
// A public API validates and publishes, a worker
// consumes and persists, and `events` is a shorthand
// that expands into its own chain of queue -> worker -> storage.
service Ingest;
use {
db Postgres;
queue NATS;
}
api Submit;
worker Processor;
events PageView;
pipeline Submit:
Validate
-> Queue
-> Return;
pipeline Processor:
Enrich
-> Store;
Here's a multi-service example (sim-three-service):
// Three services, one request
//
// `Intake` synchronously calls `Billing` and gets
// a real response, then publishes an event that
// `Fulfillment` can react to independently.
//
// This represents a synchronous call, an async stream,
// and independent storage ownership by each service.
project ThreeService;
record Order {
id: Uuid;
total: Float;
}
record ChargeRecord {
id: Uuid;
order_id: Uuid;
amount: Float;
}
record Shipment {
id: Uuid;
order_id: Uuid;
}
stream OrderAccepted: Order;
service Intake {
use { queue NATS; }
api SubmitOrder: Order {
method: POST;
path: "/orders";
}
pipeline SubmitOrder:
call Billing.Charge
-> publish OrderAccepted
-> Return;
}
service Billing {
use { db Postgres; }
table Charges: ChargeRecord;
api Charge: Order {
method: POST;
path: "/charge";
}
handler RecordCharge(order: Order) -> Order {
db.insert(Charges, ChargeRecord { id: Uuid.new(), order_id: order.id, amount: order.total });
return order;
}
pipeline Charge:
RecordCharge
-> Return;
}
service Fulfillment {
use { db Postgres; queue NATS; }
table Shipments: Shipment;
worker Ship on OrderAccepted;
handler RecordShipment(order: Order) -> Order {
db.insert(Shipments, Shipment { id: Uuid.new(), order_id: order.id });
return order;
}
pipeline Ship:
RecordShipment;
}
Today's capabilities:
- Compile into five language targets - Rust, Python, TypeScript, Go, and/or Java.
- Thirteen infrastructure capabilities identically implemented across all five targets.
- Simulate the whole system deterministically, in-memory, no Docker required.
- Architecture changes can be classified, renamed, or migrated safely.
- A usable LSP and an MCP tool surface for agents.
Today's limitations, for now:
- Many-to-many
Reference<T>fields type-check properly, but the generated API can't read or write them yet. - No field-level validation; handler logic enforces business rules instead.
- Destructive schema changes are refused; those must be written by hand.
- With no path onto an existing codebase, CIaC is for greenfield systems only.
You can learn more about the language itself in the docs. There are plenty of other examples as well.
AI Disclaimer
Needless to say for software development (AI-assisted development especially), it is in the best interest of any software project to be heavily curated throughout its lifetime.
I made sure to use gen AI tools for the implementation deliberately; I carefully hand-crafted a high-level language for combining arbitrary backend service components into coherent and simulation-verified codegen artifacts.
Over the course of the project's development, I committed to regular code reviews and testing to ensure the AI-generated code is up to par with my standards as a maintainer.
To help with maintenance, there are fleshed-out test and benchmark suites for both the compiler and codegen artifacts. These have been run prior to each release since their inception.
If you're interested in making additions or changes to the project (with AI or not), all I ask is that you hold yourself to similar review and testing standards.
Get involved
You can learn more about how to use CIaC from this discussion thread.
Additionally, you can install the compiler from here, or follow the readme instructions instead.
Feel free to take a look around the project, try it out, open issues/PRs, and ask any questions you may have. I'm more than happy to discuss the project!
Collaboration and constructive criticism are welcomed!
Voxel graphical calculator
I just released v0.1.0 of HyperVox, a voxel graphical calculator for N-dimensional mathematical expressions.
It takes one or more mathematical expressions and renders them as 3D voxel graphics. Expressions are evaluated over an N-dimensional space, so shapes can be defined in more than three dimensions.
Each expression is parsed and evaluated into a sign grid. All sign grids are composited front-to-back into one voxel grid, where each voxel takes the color of the first expression that fills it. A single mesh with per-corner ambient occlusion is built from that composite.
With more than three dimensions, only the three dimensions mapped to the X, Y, Z axes vary spatially; the rest are held at fixed values, so the render shows a 3D slice of the N-dimensional space.
- Repo: https://github.com/timasoft/hypervox
- Live single-threaded WASM build: https://timasoft.github.io/hypervox/
AI Usage: At the start of this project, I used AI extensively to understand how to use Bevy and compile it to WASM (though AI didn't help much with the WASM compilation part). Since then, I've used AI to analyze the codebase and generate optimization ideas, which I then benchmark and verify. If an AI-suggested optimization gives a >10% speedup, I ask it a few questions about the implementation details and then write the final code myself, as AI often struggles to produce optimal, idiomatic Rust. I also use AI to review almost all of my commits/PRs to catch anything I might have missed or done unidiomatically.
Why I'm posting: I have run out of ideas for optimizations and would love your help finding other ways to speed up the regeneration time!
Current optimizations:
- Using a custom expression evaluator (
hypervox_expr) instead ofevalexpr - "Compiling" expressions to
Box<dyn Fn>instead of evaluating with a large match block - Constant folding and algebraic simplification
- Common subexpression elimination (CSE) using
let n = x in {expr} - Fused MulAdd
- Multi-level invariant hoisting
unsafe set_lento skip zeroing memory (buffer is immediately overwritten)- Multi-threaded memory copying using
split_at_mutandcopy_from_slice - Ambient Occlusion (AO) caching
- Multi-threaded grid/composite computation
Also, if you have ideas about new features or UI improvements, please share them with me!
Best resources to start learning Rust as a beginner?
Hey everyone,
I'm planning to dive into Rust and wanted to ask the community for recommendations on the best starting point.
I know The Rust Programming Language book (the official documentation) and Rustlings are heavily recommended, but I'd love to know what worked best for you personally when you were starting out.
Looking for recommendations on:
Interactive courses, videos, or tutorials that do a great job explaining core concepts like ownership and borrowing
Good beginner-friendly project ideas to put the basics into practice
Useful tools, YouTube channels, or blogs you found helpful
Appreciate any tips or guidance!
Don't forget, the next Clippy cat can now be nominated!
There was only one submission last time, this needs to get better for 1.99!
Nominate here: https://github.com/rust-lang/rust-clippy/pull/17578
I just finished the official handbook guide what next?
I just finished the handbook and now i dont know what to do next i feel like ive learned a lot but i can still improve and i havent made any programms in rust except the ones in the handbook so if anyone can recommend what to do next i would really appreciate it!
Today I learnt #[expect()]
#[expect()] SHOULD BE TAUGHT IN THE FIRST YEAR OF ELEMENTARY SCHOOL!!!
#[allow()] should be prohibited, a crime punishable by death!
[forbid(clippy::allow_attributes)] should be the default Rust, not even needed to write!