Rustのplaygroundを作る

html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Rust Execute</title>
  <style>
    #editor { width: 800px; height: 300px; }
    #output { white-space: pre-wrap; border: 1px solid #ccc; padding: 10px; margin-top: 10px; }
  </style>
</head>
<body>
  <h2>Rust Editor</h2>
  <div id="editor"></div>
  <button onclick="runRust()">Run</button>
  <h3>Output</h3>
  <div id="output"></div>
  <script src="https://unpkg.com/monaco-editor@0.45.0/min/vs/loader.js"></script>
  <script>
    let editor;
    require.config({ paths: { vs: 'https://unpkg.com/monaco-editor@0.45.0/min/vs' }});
    require(['vs/editor/editor.main'], function () {
      editor = monaco.editor.create(document.getElementById('editor'), {
        value: `fn main() {\n    println!("Hello from Rust!");\n}`,
        language: 'rust',
        theme: 'vs-dark'
      });
    });

    async function runRust() {
      const code = editor.getValue();
      const res = await fetch('/run-rust', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ code })
      });
      const result = await res.text();
      document.getElementById('output').innerText = result;
    }
  </script>
</body>
</html>

node

const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const { exec } = require('child_process');
const path = require('path');

const app = express();
app.use(bodyParser.json());
app.use(express.static(__dirname)); 

app.post('/run-rust', (req, res) => {
    const code = req.body.code;
    const filename = `temp_${Date.now()}.rs`;
    const filepath = path.join(__dirname, filename);

    fs.writeFileSync(filepath, code);    
    const outputBinary = filepath.replace('.rs', '');

    exec(`rustc ${filepath} -o ${outputBinary}`, (err, _, stderr) => {
        if (err) {
            fs.unlinkSync(filepath);
            return res.send(`コンパイルエラー:\n${stderr}`);
        }

        exec(outputBinary, (runErr, stdout, runStderr) => {
            fs.unlinkSync(filepath);
            fs.unlinkSync(outputBinary);
      
            if (runErr) {
              return res.send(`実行エラー:\n${runStderr}`);
            }
      
            res.send(stdout);
        });
    });
});

const PORT = 3000;
const HOST = '192.168.33.10';
app.listen(PORT, HOST, () => console.log(`http://192.168.33.10:${PORT} で実行中`));