Here are some Rust crates or projects I either wrote or worked on enough to be one of the maintainers. It doesn’t count stuff I wrote for work, unless it really feels like “mine” (which means just
- Github: https://github.com/thomcc/bad3d
Every so often I miss game development, and really feel the itch to get in there with some good ol math and computational geometry. This is where I go. Some features:
- Working 3D physics code that
- Supports rigidbody collisions of anything that can be made up by a list of convex polyhedra.
- Uses a fancy immediate-mode API that eventually I had hoped to make into something vaguely declarative (imagine: React-but-for-3d-scenes).
- The immediate mode API made it really annoying to implement a good broadphase so it doesn’t have one. (Look, it’s my project, I get to make the call that I’m only doing the fun bits)
- Working 3D collision detection code (Obvious given the first one).
- The algorithms it uses are GJK for detecting collisions and a slightly-modified EPA for producing the response.
- Works pretty well, and uses SIMD accelerated code for finding the support point.
- I found out that somehow collision detection driver loop (e.g. the non-SIMD part) spends 30% of it’s time in memcpy!? I need to get back and fix this…
- A implementation of 3D convex-hull, with support for producing an approximated hull with no more than N vertices
- Uses a greedy algorithm I stole shamelessly after seeing it in bullet3d and being enchanted by its simplicity.
- My implementation is worse under most metrics, but it’s mine (and also it’s useful for EPA).
- A implementation of constructive-solid-geometry operations (e.g. shape booleans).
- This is buggy. I have a proof of why it should be correct, and yet it’s buggy 😭.
- A half-edge/wing-edge mesh data structure
- Uses indices to avoid the hairy maze of pointers you often see.
- Might be where the bug in the CSG code lies but I suspect it’s either the BSP or in the math behind my so-called “proof of correctness”.
- Honestly probably some other weird shit, I really threw whatever I wanted in here without concern for it having a sane feature-set.
This one isn’t actually published on crates.io because some parts are buggy, others are unreasonably slow, and others still suffer from dubious design decisions. It’s a lot of fun to hack on, though.
- Github: https://github.com/rusqlite/rusqlite
- crates.io: https://crates.io/crates/rusqlite
- docs.rs: https://docs.rs/rusqlite
This started out as a thing I would poke for work, and now I’m a comaintainer of it. It has a lot of warts on it’s API, and maybe I’ll write about them at some point, but I hope to fix them.
- Github: https://github.com/thomcc/arcstr
- crates.io: https://crates.io/crates/arcstr
- docs.rs: https://docs.rs/arcstr
This is a thin-pointer reference counted string type. It can be constructed from a string literal for nearly zero cost (
const-compatible, no allocations, clone/drop of the literal-based
ArcStrs don’t even need to perform atomic operations).
const AMAZING: ArcStr = arcstr::literal!("amazing constant"); assert_eq!(AMAZING, "amazing constant"); let wow: ArcStr = arcstr::literal!("Wow!"); assert_eq!("Wow!", wow);
It’s one of my most recent (uh, as of 8/2020) projects, but I like it a lot.
I’m particuarly proud of it’s testing:
- It has 95% test coverage (haven’t tested a couple fatal error cases like OOM or refcount overflow, but the handling for those is “abort”…).
- It runs its tests under checkers like
miri, Address Sanitizer, Memory Sanitizer, and Thread Sanitizer.
- It has a (smaller than I’d like but you have to stop somewhere)
loom-based verification harness.
- And it tests on Linux (both 64-bit and 32-bit x86), macOS, Windows (both MSVC and GNU toolchains), 32 and 64-bit ARM, and 64-bit MIPS (which is the easiest big-endian target available). Much of the weird platforms run via
cross (e.g. qemu).
- This is clearly overkill, but I kinda want to reuse the
.github/workflows/ci.yml moving forward.
The tests really put github actions to work. Can’t believe they let me do this for free!
- Github: https://github.com/thomcc/almost
- crates.io: https://crates.io/crates/almost
- docs.rs: https://docs.rs/almost
This is a library for comparing floating point numbers that IMO is better than the popular crates for doing so (like
approx). Some key ideas:
- All comparisons with arbitrary numbers should be relative by default. They should not force users to understand terminology like ULP, and they should not use hybrid relative/absolute behavior as that breaks scale independence.
- All comparisons with zero should use an absolute tolerance.
- It’s possible to pick a default tolerance
- Github: https://github.com/thomcc/rust-base16
- crates.io: https://crates.io/crates/base16
- docs.rs: https://docs.rs/base16
I wrote this because the
hex crate was too slow. It might be obsolete now, but…. taking a look the
hex crate is still unreasonably slow. (Look, I don’t ask for much, but honestly the strings you get passed as input could be quite large…)
- Github: https://github.com/mozilla/ffi-support
- crates.io: https://crates.io/crates/ffi-support
- docs.rs: https://docs.rs/ffi-support
I wrote this for my work at Mozilla, and probably won’t maintain it now that I’ve been laid off. Still, it took a lot of care and effot, and I think it’s a good approach if you’re manually writing FFI code to expose Rust to something else.
- Github: https://github.com/thomcc/handy
- crates.io: https://crates.io/crates/handy
- docs.rs: https://docs.rs/handy
This is basically a rewrite of the
HandleMap type from ffi-support. I actually think the implementation in ffi-support is cleaner and elegant, but
handy has more features and is probably more efficient. For pure-rust use cases, most of the code I had using
handy I’ve moved over to
- Github: https://github.com/thomcc/index_vec
- crates.io: https://crates.io/crates/index_vec
- docs.rs: https://docs.rs/index_vec
This lets helps define newtype-style wrappers around
usize and use them with special Vecs and slices. The technique is used heavily in
rustc, but the code in
rustc isn’t public, and doesn’t compile on stable even if it was.
The API has a bit of jank to it because it was when I was in my phase where I refused to use proc_macro crates due to the build overhead. Now I’m a bit more pragmatic… but still wish it they didn’t cause such a compile-time hit.
- Github: https://github.com/thomcc/thin_str
- crates.io: https://crates.io/crates/thin_str
- docs.rs: https://docs.rs/thin_str
arcstr but for
Box<str> and worse. Just use
arcstr. The overhead is small. Maybe I’ll eventually update this one with the ability to initialize it from a literal though…
- Github: https://github.com/thomcc/tearor
- crates.io: https://crates.io/crates/tearor
- docs.rs: https://docs.rs/tearor
I wrote a whole blog post on this one. Also probably don’t use it? Actually, I’ve been meaning to write a followup on “when might using it be a good idea”. It’s good for a few cases.
- Github: https://github.com/thomcc/rust-more-asserts
- crates.io: https://crates.io/crates/more-asserts
- docs.rs: https://docs.rs/more-asserts
This is one of my first crates and it’s eh. It was better when
#[macro_use] was conditional, as it is
more_asserts::assert_lt!(...) is just tedious. Somehow it’s one of my most popular? Being early is better than being good, I guess…
- Github: https://github.com/thomcc/chek
- crates.io: https://crates.io/crates/chek
- docs.rs: https://docs.rs/chek
This is a less tedious to type version of more-asserts. It also has a mode to automatically outline your assertions, but I didn’t realize how important that was so I didn’t enable it by default.
That said nobody uses it they just use
more-asserts. I’ve been tempted to deprecate the former for it, but… eh. That code still works fine, why put people through the churn?
- Github: https://github.com/thomcc/core_detect
- crates.io: https://crates.io/crates/core_detect
- docs.rs: https://docs.rs/core_detect
This is a
no_std version of the
On x86/x86_64, runtime feature detection is done via the
cpuid instruction, and so it doesn’t require the stdlib.
- Github: https://github.com/thomcc/atomic_float
- crates.io: https://crates.io/crates/atomic_float
- docs.rs: https://docs.rs/atomic_float
Small crate providing
AtomicF64 types that act more or less identically to the integer atomic types in the stdlib.
- Github: https://github.com/thomcc/lazy_id
- crates.io: https://crates.io/crates/lazy_id
- docs.rs: https://docs.rs/lazy_id
lazy_id::Id, a thread-safe 64-bit id that only initializes itself to a specific value when you use it rather than when you create it. It works with no_std (without liballoc either), and is entirely lock-free.
The readme on github/crates.io does a good job explaining why this is can be useful.
- Github: https://github.com/thomcc/ulock-sys
- crates.io: https://crates.io/crates/ulock-sys
- docs.rs: https://docs.rs/ulock-sys
Bindings for Darwin’s (unstable) futex-like API. See this section of my futex-like blog post for some discussion of this API.
imgui-sys and related crates
- Github: https://github.com/imgui-rs/imgui-rs
- crates.io: https://crates.io/crates/imgui
- docs.rs: https://docs.rs/imgui
As of November 2020, I’m the new maintainer of the Rust bindings to the excellent Dear ImGui library. I haven’t done much here yet (it hasn’t been long, and I got terribly sick recently), but you can read about some of my plans in my comments in the issue about maintainer changes.
- Github: https://github.com/thomcc/startup
- crates.io: https://crates.io/crates/startup
- docs.rs: https://docs.rs/startup
Static initialization for Rust.
Run code before main or at module initialization time. Functionally equivalent to the
ctor crate, but supports more platforms, compiles (much, much) faster, and avoids some things that can cause safety issues (no
#[dtor], and we don’t have an equivalent to using
#[ctor] on a static).