Skip to content

Commit 24f9bd9

Browse files
committed
Rewrite it in Rust
1 parent 3ce2c95 commit 24f9bd9

File tree

6 files changed

+60
-45
lines changed

6 files changed

+60
-45
lines changed

Diff for: README.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# React `use c`
1+
# React `use rust`
22

3-
Use C in your React!
3+
Use Rust in your React!
44

55
<img width="590" alt="image" src="https://github.com/elnardu/react-use-c/assets/8999001/495c39d6-3fb1-437d-9af0-03020c215159">
66

7-
https://github.com/elnardu/react-use-c/assets/8999001/24a433d9-af89-4962-a0a1-ba6533092d0b
87

98
## TODO
109

10+
- [ ] Package Rust for npm
1111
- [ ] Add more folders and files with code that does nothing to look more professional
12-
- [ ] Create `create-react-use-c` package cuz this ecosystem is broken
12+
- [ ] Create `create-react-use-rust` package cuz this ecosystem is broken
1313
- [ ] Add typescript support
1414
- [ ] Make somebody else figure out publishing this to npm (I am still not over it)
1515
- [ ] Remove typescript support

Diff for: build.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,29 @@ function findClosingBrace(string) {
1717
return null;
1818
}
1919

20-
function transformToUseC(args) {
20+
function transformToUseRust(args) {
2121
const content = fsButWihtoutPromises.readFileSync(args.path, "utf8");
22-
const splits = content.split(/["']use c["'];/);
22+
const splits = content.split(/["']use rust["'];/);
2323
let result = splits[0];
2424
for (let i = 1; i < splits.length; i++) {
25-
const endOfCCode = findClosingBrace(splits[i]);
26-
const cCode = splits[i].slice(0, endOfCCode);
27-
result += `return runC("${encodeURIComponent(cCode)}");`;
28-
result += splits[i].slice(endOfCCode, splits[i].length);
25+
const endOfRustCode = findClosingBrace(splits[i]);
26+
const rustCode = splits[i].slice(0, endOfRustCode);
27+
result += `return runRust("${encodeURIComponent(rustCode)}");`;
28+
result += splits[i].slice(endOfRustCode, splits[i].length);
2929
}
3030
return result;
3131
}
3232

33-
const useCPlugin = {
34-
name: "use-c",
33+
const useRustPlugin = {
34+
name: "use-rust",
3535
setup(build) {
3636
build.onLoad({ filter: /.js$/ }, (args) => ({
37-
contents: transformToUseC(args),
37+
contents: transformToUseRust(args),
3838
loader: "js",
3939
}));
4040

4141
build.onLoad({ filter: /.jsx$/ }, (args) => ({
42-
contents: transformToUseC(args),
42+
contents: transformToUseRust(args),
4343
loader: "jsx",
4444
}));
4545
},
@@ -64,7 +64,7 @@ async function build() {
6464
minify: true,
6565
bundle: true,
6666
sourcemap: true,
67-
plugins: [useCPlugin],
67+
plugins: [useRustPlugin],
6868
});
6969

7070
await fs.cp("index.html", "dist/index.html");

Diff for: client.jsx

+10-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ${strings[0]}
2020
return randomClassId;
2121
}
2222

23-
async function runC(code) {
23+
async function runRust(code) {
2424
const res = await fetch("/rpc/rce", {
2525
method: "POST",
2626
body: JSON.stringify({ code: code }),
@@ -39,30 +39,29 @@ const appStyles = css`
3939

4040
const App = () => (
4141
<div className={appStyles}>
42-
<h1>React use C demo</h1>
42+
<h1>React use Rust demo</h1>
4343
<Demo />
4444
</div>
4545
);
4646

4747
const Demo = () => {
4848
const [output, setOutput] = useState(null);
49-
const cHelloWorld = async () => {
50-
"use c";
51-
#include <stdio.h>
52-
int main() {
53-
printf("Hello from C!\n");
54-
return 0;
49+
const rustHelloWorld = async () => {
50+
"use rust";
51+
fn main() {
52+
println!("Hello, world from Rust!");
53+
println!("Also hi HN!");
5554
}
5655
};
5756
const onClick = async () => {
58-
const out = await cHelloWorld();
57+
const out = await rustHelloWorld();
5958
setOutput(out.stdout);
6059
};
6160

6261
return (
6362
<div>
64-
<button onClick={onClick}>Run C code!</button>
65-
<p>Output from C:</p>
63+
<button onClick={onClick}>Run Rust code!</button>
64+
<p>Output from Rust:</p>
6665
<pre>{ output }</pre>
6766
</div>
6867
);

Diff for: index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<title>React use C demo</title>
6+
<title>React use Rust demo</title>
77
</head>
88
<body>
99
<div id="app"></div>

Diff for: package.json

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "react-use-c",
2+
"name": "react-use-rust",
33
"version": "1.0.0",
4-
"description": "Use C in your server side react components",
4+
"description": "Use Rust in your server side react components",
55
"main": "this field is so weird",
66
"scripts": {
77
"start": "npm run build && node server.js",
@@ -11,7 +11,7 @@
1111
},
1212
"repository": {
1313
"type": "git",
14-
"url": "git+https://github.com/elnardu/react-use-c.git"
14+
"url": "git+https://github.com/elnardu/react-use-rust.git"
1515
},
1616
"keywords": [
1717
"C",
@@ -24,16 +24,15 @@
2424
"author": "me",
2525
"license": "WTFPL",
2626
"bugs": {
27-
"url": "https://github.com/elnardu/react-use-c/issues"
27+
"url": "https://github.com/elnardu/react-use-rust/issues"
2828
},
29-
"homepage": "https://github.com/elnardu/react-use-c#readme",
29+
"homepage": "https://github.com/elnardu/react-use-rust#readme",
3030
"devDependencies": {
3131
"esbuild": "0.19.5",
3232
"react": "^18.2.0",
3333
"react-dom": "^18.2.0"
3434
},
3535
"dependencies": {
36-
"express": "^4.18.2",
37-
"@oven/zig": "0.12.0-dev.1286"
36+
"express": "^4.18.2"
3837
}
3938
}

Diff for: server.js

+28-11
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ const port = process.env.PORT ?? 3000;
1111
app.use(express.static("dist"));
1212
app.use(express.json());
1313

14-
const zigPath = "node_modules/@oven/zig/zig";
15-
1614
function spawn(command, args) {
1715
return new Promise((resolve) => {
1816
// damn this api is shit
@@ -40,29 +38,48 @@ function spawn(command, args) {
4038

4139
function maketmp() {
4240
return new Promise((resolve, reject) => {
43-
fs.mkdtemp(path.join(os.tmpdir(), "use-c"), (err, dir) => {
41+
fs.mkdtemp(path.join(os.tmpdir(), "use-rust"), (err, dir) => {
4442
if (err !== null) reject(err);
4543
else resolve(dir);
4644
});
4745
});
4846
}
4947

50-
async function runC(code) {
48+
async function runRust(code) {
5149
const dir = await maketmp();
52-
const cFile = path.join(dir, "main.c");
50+
const rustFile = path.join(dir, "main.rs");
5351
const outFile = path.join(dir, "main");
54-
await fsPromises.writeFile(cFile, decodeURIComponent(code));
55-
await spawn(zigPath, ["cc", cFile, "-o", outFile]);
52+
await fsPromises.writeFile(rustFile, decodeURIComponent(code));
53+
await spawn("rustc", [rustFile, "-o", outFile]);
5654
const out = await spawn(outFile, []);
5755
return out;
5856
}
5957

6058
app.post("/rpc/rce", async (req, res) => {
6159
const { code } = req.body;
62-
const out = await runC(code);
60+
const out = await runRust(code);
6361
res.json(out);
6462
});
6563

66-
app.listen(port, () => {
67-
console.log(`Listening on port ${port}`);
68-
});
64+
async function checkRust() {
65+
try {
66+
const out = await spawn("rustc", ["--version"]);
67+
if (out.code !== 0) {
68+
throw new Error("Rust is not installed");
69+
}
70+
} catch (e) {
71+
console.error("Please install rust");
72+
console.error(" curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh");
73+
console.error("Bye!");
74+
process.exit(1);
75+
}
76+
}
77+
78+
// Can somebody tell me if top level async is finally ok to use?
79+
(async () => {
80+
await checkRust();
81+
82+
app.listen(port, () => {
83+
console.log(`Listening on port ${port}`);
84+
});
85+
})();

0 commit comments

Comments
 (0)