sailfish_compiler/
util.rs1use std::fs;
2use std::io::{self, Write};
3use std::path::{Path, PathBuf};
4use std::process::{Command, Stdio};
5
6pub fn read_to_string(path: &Path) -> io::Result<String> {
7 let mut content = std::fs::read_to_string(path)?;
8
9 if content.ends_with('\n') {
11 content.truncate(content.len() - 1);
12 if content.ends_with('\r') {
13 content.truncate(content.len() - 1);
14 }
15 }
16
17 Ok(content)
18}
19
20fn find_rustfmt() -> io::Result<Option<PathBuf>> {
21 let mut toolchain_dir = home::rustup_home()?;
22 toolchain_dir.push("toolchains");
23 for e in fs::read_dir(toolchain_dir)? {
24 let mut path = e?.path();
25 path.push("bin");
26 path.push("rustfmt");
27 if path.exists() {
28 return Ok(Some(path));
29 }
30 }
31
32 Ok(None)
33}
34
35pub fn rustfmt_block(source: &str) -> io::Result<String> {
37 let rustfmt = match find_rustfmt()? {
38 Some(p) => p,
39 None => {
40 return Err(io::Error::new(
41 io::ErrorKind::NotFound,
42 "rustfmt command not found",
43 ))
44 }
45 };
46
47 let mut new_source = String::with_capacity(source.len() + 11);
48 new_source.push_str("fn render()");
49 new_source.push_str(source);
50
51 let mut child = Command::new(rustfmt)
52 .args(["--emit", "stdout", "--color", "never", "--quiet"])
53 .stdin(Stdio::piped())
54 .stdout(Stdio::piped())
55 .stderr(Stdio::null())
56 .spawn()?;
57
58 let stdin = child
59 .stdin
60 .as_mut()
61 .ok_or_else(|| io::Error::from(io::ErrorKind::BrokenPipe))?;
62 stdin.write_all(new_source.as_bytes())?;
63
64 let output = child.wait_with_output()?;
65
66 if output.status.success() {
67 let mut s =
68 String::from_utf8(output.stdout).expect("rustfmt output is non-UTF-8!");
69 let brace_offset = s.find('{').unwrap();
70 s.replace_range(..brace_offset, "");
71 Ok(s)
72 } else {
73 Err(io::Error::new(
74 io::ErrorKind::Other,
75 "rustfmt command failed",
76 ))
77 }
78}
79
80#[cfg(feature = "procmacro")]
81pub fn filetime(input: &Path) -> filetime::FileTime {
82 use filetime::FileTime;
83 fs::metadata(input)
84 .and_then(|metadata| metadata.modified())
85 .map_or(FileTime::zero(), FileTime::from_system_time)
86}