use gleam_core::{ error::{Error, FileIoAction, FileKind, Result, StandardIoAction, Unformatted}, io::Content, io::OutputFile, }; use std::{io::Read, str::FromStr}; use camino::{Utf8Path, Utf8PathBuf}; pub fn run(stdin: bool, check: bool, files: Vec) -> Result<()> { if stdin { process_stdin(check) } else { process_files(check, files) } } fn process_stdin(check: bool) -> Result<()> { let src = read_stdin()?.into(); let mut out = String::new(); gleam_core::format::pretty(&mut out, &src, Utf8Path::new(""))?; if !check { print!("{out}"); return Ok(()); } if src != out { return Err(Error::Format { problem_files: vec![Unformatted { source: Utf8PathBuf::from(""), destination: Utf8PathBuf::from(""), input: src, output: out, }], }); } Ok(()) } fn process_files(check: bool, files: Vec) -> Result<()> { if check { check_files(files) } else { format_files(files) } } fn check_files(files: Vec) -> Result<()> { let problem_files = unformatted_files(files)?; if problem_files.is_empty() { Ok(()) } else { Err(Error::Format { problem_files }) } } fn format_files(files: Vec) -> Result<()> { for file in unformatted_files(files)? { crate::fs::write_output(&OutputFile { path: file.destination, content: Content::Text(file.output), })?; } Ok(()) } pub fn unformatted_files(files: Vec) -> Result> { let mut problem_files = Vec::with_capacity(files.len()); for file_path in files { let path = Utf8PathBuf::from_str(&file_path).map_err(|e| Error::FileIo { action: FileIoAction::Open, kind: FileKind::File, path: Utf8PathBuf::from(file_path), err: Some(e.to_string()), })?; if path.is_dir() { for path in crate::fs::gleam_files(&path) { format_file(&mut problem_files, path)?; } } else { format_file(&mut problem_files, path)?; } } Ok(problem_files) } fn format_file(problem_files: &mut Vec, path: Utf8PathBuf) -> Result<()> { let src = crate::fs::read(&path)?.into(); let mut output = String::new(); gleam_core::format::pretty(&mut output, &src, &path)?; if src != output { problem_files.push(Unformatted { source: path.clone(), destination: path, input: src, output, }); } Ok(()) } pub fn read_stdin() -> Result { let mut src = String::new(); let _ = std::io::stdin() .read_to_string(&mut src) .map_err(|e| Error::StandardIo { action: StandardIoAction::Read, err: Some(e.kind()), })?; Ok(src) }