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