CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
sagemathinc

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/project/formatters/rust-format.ts
Views: 687
1
/*
2
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
3
* License: MS-RSL – see LICENSE.md for details
4
*/
5
6
import { callback } from "awaiting";
7
import { spawn } from "child_process";
8
import { readFile, unlink, writeFile } from "node:fs";
9
import * as tmp from "tmp";
10
11
import { Options } from "./index";
12
13
function close(proc, cb): void {
14
proc.on("close", (code) => cb(undefined, code));
15
}
16
17
// ref: https://github.com/rust-lang/rustfmt ... but the configuration comes with project specific toml files
18
19
function run_rustfmt(input_path: string) {
20
return spawn("rustfmt", [input_path]);
21
}
22
23
function cleanup_error(out: string, tmpfn: string): string {
24
return out
25
.split("\n")
26
.filter((line) => line.indexOf(tmpfn) < 0)
27
.join("\n");
28
}
29
30
export async function rust_format(
31
input: string,
32
options: Options,
33
logger: any
34
): Promise<string> {
35
// create input temp file
36
const input_path: string = await callback(tmp.file);
37
try {
38
// logger.debug(`rustfmt tmp file: ${input_path}`);
39
await callback(writeFile, input_path, input);
40
41
// spawn the html formatter
42
let formatter;
43
44
switch (options.parser) {
45
case "rustfmt":
46
formatter = run_rustfmt(input_path /*, logger*/);
47
break;
48
default:
49
throw Error(`Unknown Rust code formatting utility '${options.parser}'`);
50
}
51
// stdout/err capture
52
let stdout: string = "";
53
let stderr: string = "";
54
// read data as it is produced.
55
formatter.stdout.on("data", (data) => (stdout += data.toString()));
56
formatter.stderr.on("data", (data) => (stderr += data.toString()));
57
// wait for subprocess to close.
58
const code = await callback(close, formatter);
59
if (code >= 1) {
60
stdout = cleanup_error(stdout, input_path);
61
stderr = cleanup_error(stderr, input_path);
62
const err_msg = [stdout, stderr].filter((x) => !!x).join("\n");
63
logger.debug(`rustfmt error: ${err_msg}`);
64
throw Error(err_msg);
65
}
66
67
// all fine, we read from the temp file
68
const output: Buffer = await callback(readFile, input_path);
69
const s: string = output.toString("utf-8");
70
// logger.debug(`rust_format output s ${s}`);
71
return s;
72
} finally {
73
unlink(input_path, () => {});
74
}
75
}
76
77