agentleFS
morganlintonmorganlinton/BeautifulRust/skills/rust-port/SKILL.md

rust-port

Skill1.8k starsChanged 12 days agoMITView on GitHub

Port code from C, C++, Python, Go, JavaScript, or TypeScript into idiomatic Rust that keeps the original behavior: ownership instead of manual memory, Result instead of error codes and exceptions, enums instead of flag ints and magic strings, and tests that prove the port matches. Use this whenever the user asks to port, translate, convert, migrate, or rewrite code in Rust ("rewrite this in Rust", "what would this look like in Rust", "move this module to Rust"), even if they don't say "port". Pairs with the rust-best-practices skill, which covers the target code's style.

7 other projects use a version of this, 1 of them edited; 2 new projects in the last 4 weeks, against 0 the 4 before.

Adopted by

Surging: 2 new projects took it in the last 4 weeks, none the 4 weeks before.thin data

Week of Sep 13: 0 new projectsWeek of Sep 20: 0 new projectsWeek of Sep 27: 0 new projectsWeek of Oct 4: 0 new projectsWeek of Oct 11: 0 new projectsWeek of Oct 18: 0 new projectsWeek of Oct 25: 1 new projectWeek of Nov 1: 1 new project
Sep 2026Oct 2026Nov 2026
New projects taking a version of this file each week, over the 8 weeks our latest run read: only 2 in all, so this is a hint, not a trend.

Most recently taken up by

Who's talking about morganlinton/BeautifulRust

The biggest 5 of 51 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 51

Talked about on GitHub, YouTube and the web (51 times).

On GitHub · 34

29 more on GitHub

On YouTube · 15

10 more on YouTube
  • Other versions7 projects use a version of this.

    Word for word · 2

    1. tuan3w/herdr-mobile★ 29100% same
    2. XGENT-ai/skills★ 1100% same

    Edited · 1

    1. fedemelo/agent-config★ 499% same

    Wrote their own version · 4

    1. po4yka/rust-skills★ 5same name
    2. kabudu/engineering-agent-skills★ 3same name
    3. weedmo/skills★ 1same name
    4. promptctl/cc-candybar★ 0same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository2 other files it gives its agents.

The file

We split this skill into the rules it gives an agent

6 rules. 0 are common, 4 are distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    List the observable behavior: every public function, its inputs, its outputs, and every way it can fail.

    line 23
  2. Distinctive:

    If the original has a bug or an ambiguity, keep its behavior, flag it in the porting notes, and let the user decide.

    line 31
  3. Very specific:

    Don't write unsafe or use raw pointers unless the port must talk to C through FFI, and then confine it as the rust-best-practices skill …

    line 62
  4. Very specific:

    Don't reimplement the source language's runtime: Use str::lines, str::trim, str::parse, and char methods, not hand-written copies of …

    line 93
  5. Distinctive:

    Run these if a Rust toolchain is available, and fix everything before reporting:

    line 118
  6. Distinctive:

    Every ported test must pass.

    line 126

“Common” is measured: kept by at least 6 in 10 of the 5 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Rust port

The goal is the Rust a Rust developer would have written to solve the same problem, with the same observable behavior. A line-by-line transliteration (C written in Rust syntax, or Python with Box<dyn Any>) compiles but keeps every problem the original had and adds the borrow checker on top. Port the behavior, not the structure.

1. Understand the original before writing anything

  1. Read the code and its tests, and anything that calls it, if you have it.
  2. List the observable behavior: every public function, its inputs, its outputs, and every way it can fail. Include the quiet parts, which are where ports go wrong: ordering of results, how ties break, what happens on empty input, whitespace and case handling, integer limits, and what counts as an error versus a valid edge case.
  3. Note what is incidental, meaning things the original only does because of its language: manual memory management, out-parameters, NULL returns, global state, fixed-size buffers, a class that exists only to group functions, or isinstance checks. These don't carry over.
  4. If the original has a bug or an ambiguity, keep its behavior, flag it in the porting notes, and let the user decide. A port is not the place to silently fix things.

2. Port the tests first

Translate the original tests into Rust tests before porting the implementation. Keep one Rust test per original test, with a name that maps back to it, so a reader can check coverage. The tests are the definition of "same behavior". If the original has no tests, write characterization tests from the behavior list in step 1.

3. Design the Rust API, then implement it

Decide the public types and signatures from the behavior list, not from the original's shape. Then implement against the ported tests.

From C and C++

In the originalIn Rust
malloc/free, new/delete, create/destroy pairsOwned types (String, Vec, Box) dropped automatically; Drop for anything else
NULL meaning "absent"Option<T>
Error codes (-1, ERR_* defines), errnoResult<T, E> with an error enum, one variant per code, implementing Display and std::error::Error
Out-parameters (int *err_line, long *out)Return values: put the data in the Ok value or the error variant
Flag bitmasks (FLAG_A | FLAG_B)An options struct with named fields and Default, or the bitflags crate; never a raw u32
char * plus length, strcmp, strcasecmp&str/String, ==, eq_ignore_ascii_case
Pointer plus count, iterator by indexSlices, iterators
Fixed-size buffers and their truncationGrowable types; drop the limit unless the limit is behavior
#define constants and macrosconst, enums, and functions
Global or static mutable stateA struct the caller owns
strtol and friendsstr::parse with the matching integer type; map parse failures to your error enum

Don't write unsafe or use raw pointers unless the port must talk to C through FFI, and then confine it as the rust-best-practices skill describes.

From Python

In the originalIn Rust
An exception hierarchyOne error enum (or one per area) with a variant per exception class; data attributes become variant fields
None as a valueOption<T>
Strings used as a closed set (kind in ("build", "test"))An enum, with FromStr and Display for the text form
Dicts or classes used as recordsStructs with named fields
dict iteration order (insertion order is guaranteed)Vec or an ordered map when order is observable; a plain HashMap silently changes output order
Duck typing, isinstanceTraits or enums
Unbounded intA sized integer chosen on purpose, with overflow handled (checked_*) where input can be large
sorted(..., key=...)sort_by_key or sort_by; both are stable, like Python's
str.splitlines(), strip(), isalnum()lines(), trim(), char::is_alphanumeric; check edge cases such as \r\n, Unicode, and empty strings against the original
try/except around a parse? with a mapped error, or match on the Result

From Go, JavaScript, and TypeScript

  • Go (value, error) returns become Result; nil becomes Option; interfaces become traits; goroutines and channels become threads with std::sync::mpsc or async tasks, depending on what the original needs.
  • JavaScript null and undefined become Option; thrown errors become Result; plain objects become structs; numbers become a sized integer or f64, chosen on purpose.

4. Keep the port proportionate

A port that matches the original on every possible input is usually the wrong goal. Match it on the inputs it actually receives, and use Rust's standard library for the rest.

  • Don't reimplement the source language's runtime. Use str::lines, str::trim, str::parse, and char methods, not hand-written copies of Python's splitlines, strip, int(), or repr(), or of C's locale-dependent isspace and strtol. Where Rust's behavior differs only on exotic input, such as Unicode digits, non-ASCII whitespace, or unbounded integers, list the difference in the porting notes instead of coding around it. Write a compatibility shim only when the user says those inputs occur.
  • Don't grow the API. Port the public surface the original has, plus the standard trait impls Rust callers expect (Debug, Clone, Display, Error, FromStr, Default, and IntoIterator for collections). Skip builders, Index impls, FromIterator, Extend, and custom iterator types unless the original's callers need them.
  • Keep the algorithm unless it's wrong. Swap in a different algorithm only to fix a real problem, such as quadratic behavior on realistic input, and say so in the notes.
  • Check the size. Count code lines, excluding tests, comments, and doc comments. A port from C or C++ usually lands near the original's size. A port from Python or JavaScript usually lands at two to three times the original, because types, error enums, and their trait impls are explicit in Rust. Much more than that usually means one of the three habits above.

Differential testing against the original is worth doing, but a few dozen realistic and edge-case inputs answer the question. A fuzzing harness over millions of inputs usually just finds exotic divergences that belong in the notes.

5. Verify

Run these if a Rust toolchain is available, and fix everything before reporting:

cargo build
cargo test
cargo clippy --all-targets -- -D warnings

Every ported test must pass. If the original's tests can be run too, run them and compare results on the same inputs.

6. Write the porting notes

Alongside the code, write a short PORTING.md that a reviewer can check in a few minutes:

  • API mapping: a table from each original function or type to its Rust equivalent.
  • Test mapping: each original test and the Rust test that covers it.
  • Deliberate differences: anything that now behaves differently and why, such as an out-of-memory error that no longer exists, a fixed buffer limit that's gone, or exotic input where Rust's standard library behaves differently from the original's.
  • Preserved quirks: odd behavior kept on purpose, so nobody "fixes" it by accident.
  • Verification: which commands you ran and their result, or a plain statement that you couldn't run them.

For the style of the Rust itself, follow the rust-best-practices skill if it is installed.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.