1 use gleam_core::{
2 error::{Error, FileIoAction, FileKind, Result, StandardIoAction, Unformatted},
3 io::OutputFile,
4 };
5 use std::{io::Read, path::PathBuf, str::FromStr};
6
run(stdin: bool, check: bool, files: Vec<String>) -> Result<()>7 pub fn run(stdin: bool, check: bool, files: Vec<String>) -> Result<()> {
8 if stdin {
9 process_stdin(check)
10 } else {
11 process_files(check, files)
12 }
13 }
14
process_stdin(check: bool) -> Result<()>15 fn process_stdin(check: bool) -> Result<()> {
16 let src = read_stdin()?;
17 let mut out = String::new();
18 gleam_core::format::pretty(&mut out, &src)?;
19
20 if !check {
21 print!("{}", out);
22 return Ok(());
23 }
24
25 if src != out {
26 return Err(Error::Format {
27 problem_files: vec![Unformatted {
28 source: PathBuf::from("<standard input>"),
29 destination: PathBuf::from("<standard output>"),
30 input: src,
31 output: out,
32 }],
33 });
34 }
35
36 Ok(())
37 }
38
process_files(check: bool, files: Vec<String>) -> Result<()>39 fn process_files(check: bool, files: Vec<String>) -> Result<()> {
40 if check {
41 check_files(files)
42 } else {
43 format_files(files)
44 }
45 }
46
check_files(files: Vec<String>) -> Result<()>47 fn check_files(files: Vec<String>) -> Result<()> {
48 let problem_files = unformatted_files(files)?;
49
50 if problem_files.is_empty() {
51 Ok(())
52 } else {
53 Err(Error::Format { problem_files })
54 }
55 }
56
format_files(files: Vec<String>) -> Result<()>57 fn format_files(files: Vec<String>) -> Result<()> {
58 for file in unformatted_files(files)? {
59 crate::fs::write_output(&OutputFile {
60 path: file.destination,
61 text: file.output,
62 })?;
63 }
64 Ok(())
65 }
66
unformatted_files(files: Vec<String>) -> Result<Vec<Unformatted>>67 pub fn unformatted_files(files: Vec<String>) -> Result<Vec<Unformatted>> {
68 let mut problem_files = Vec::with_capacity(files.len());
69
70 for file_path in files {
71 let path = PathBuf::from_str(&file_path).map_err(|e| Error::FileIo {
72 action: FileIoAction::Open,
73 kind: FileKind::File,
74 path: PathBuf::from(file_path),
75 err: Some(e.to_string()),
76 })?;
77
78 if path.is_dir() {
79 for path in crate::fs::gleam_files_excluding_gitignore(&path) {
80 format_file(&mut problem_files, path)?;
81 }
82 } else {
83 format_file(&mut problem_files, path)?;
84 }
85 }
86
87 Ok(problem_files)
88 }
89
format_file(problem_files: &mut Vec<Unformatted>, path: PathBuf) -> Result<()>90 fn format_file(problem_files: &mut Vec<Unformatted>, path: PathBuf) -> Result<()> {
91 let src = crate::fs::read(&path)?;
92 let mut output = String::new();
93 gleam_core::format::pretty(&mut output, &src)?;
94
95 if src != output {
96 problem_files.push(Unformatted {
97 source: path.clone(),
98 destination: path,
99 input: src,
100 output,
101 });
102 }
103 Ok(())
104 }
105
read_stdin() -> Result<String>106 pub fn read_stdin() -> Result<String> {
107 let mut src = String::new();
108 let _ = std::io::stdin()
109 .read_to_string(&mut src)
110 .map_err(|e| Error::StandardIo {
111 action: StandardIoAction::Read,
112 err: Some(e.kind()),
113 })?;
114 Ok(src)
115 }
116