Ruststudio is a free IDE for Rust that is itself written in Rust: one native program of about
10 MB, Version 0.1.6 moves three things into the editor that used to need a terminal: Git, running
single tests, and adding packages. This post is less a feature list (the release article
has that) than the three design decisions I would defend, and the places where I am not sure I got it right.

Decision 1: do not implement Git, run it

The obvious route is a Git library. I chose to run the git the user already has, for one reason: a Git panel is only
trustworthy if it does exactly what git in the terminal would do.
Hooks run. .gitconfig applies. Your credential helper
signs you in, which means the IDE never sees, asks for or stores a password. When Git refuses, the panel shows Git's words and
does not retry with a force flag.

The Source Control view next to a diff, with Stage Hunk and Discard Hunk

The cost is that you depend on Git's output, and you have to be careful with names (spaces, non-English letters, renames, binary
files). The payoff is that everything the panel does is something you could have typed yourself, including staging one hunk or
only the lines you click.

One more rule I stuck to: the view never polls. It refreshes when something happens (a command, a save, a build, coming back
to the window). A timer that runs git status every second looks responsive in a demo and punishes large repositories.

Not done: a side-by-side diff, stash, interactive rebase, a commit graph. The Terminal does those, and it is the same Git.

Decision 2: the test list comes from Cargo, not from my parser

Finding tests by scanning source for #[test] is easy and wrong: macros generate tests, attributes differ (#[tokio::test],
#[rstest], #[test_case]), and doc tests are not functions at all. So there are two sources, used for different jobs:

  • The margin icons come from the source, so they appear as soon as a file is open, with no build. They are a convenience and they recognise the common attributes.
  • The Test Explorer shows what Cargo reports (package, test binary, module, test, doc tests, ignored tests), so it can disagree with the margin when macros are involved, and when it does, Cargo is right.

Run and Debug icons beside each test, and a change bar in the margin

Running is your own cargo test with the toolchain and configuration you chose. Results are shown per test while the run is
still going, and a failure gets its panic message and file:line under it and an entry in the Problems panel, so a failing
test reads like a compile error.

The Test Explorer after a run: three passed, one failed, one ignored

Debugging a test builds the test program and starts it under the debugger with that one test selected, so breakpoints in the
test and in the code it calls are hit. (On Windows with the MSVC toolchain this uses PDB symbols through lldb-dap.)

Known gaps: no coverage, no per-test timing, doc tests can be run but not debugged, and tests generated by macros get no margin
icon.

Decision 3: hints from rust-analyzer, shown but never written

Inlay hints (the type after a let, the parameter name at a call, the types along a method chain) are drawn dim inside the code.
They are not part of the buffer: the caret steps over them, they cannot end up in a diff, and View > Toggle Inlay Hints turns
them off. The same mechanism shows variable values at the end of the lines while the debugger is stopped.

Inlay hints: u32 types after let bindings and parameter names at a call

One thing I noticed while taking these screenshots: on one machine rust-analyzer could not resolve the standard library and
showed {unknown} for some types. The hints are only as good as what rust-analyzer resolves, and I would rather say so than
choose only the screenshots that look perfect.

Also in 0.1.6

Package sources you can add (any NuGet V3 feed or Cargo sparse registry, alongside nuget.org, crates.io and the Ruststudio
registries), publishing to rupm or NuGet from the IDE with a confirmation that says publishing is public, and
Go to Implementation (Shift+Alt+F12). Native iOS apps are in development and are not part of this release.