From a961355a7307844aee96493fd2edb06f965b6397 Mon Sep 17 00:00:00 2001 From: Andrew Frantz Date: Wed, 3 Jul 2024 13:10:24 -0400 Subject: [PATCH] [WIP]feat: new wdl-format crate --- Cargo.toml | 2 +- wdl-format/Cargo.toml | 12 ++++++ wdl-format/src/format.rs | 80 ++++++++++++++++++++++++++++++++++++++++ wdl-format/src/lib.rs | 10 +++++ 4 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 wdl-format/Cargo.toml create mode 100644 wdl-format/src/format.rs create mode 100644 wdl-format/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index b7e66e35..89d8cb0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ "wdl", - "wdl-ast", + "wdl-ast", "wdl-format", "wdl-gauntlet", "wdl-grammar", "wdl-lint", diff --git a/wdl-format/Cargo.toml b/wdl-format/Cargo.toml new file mode 100644 index 00000000..e5e07b67 --- /dev/null +++ b/wdl-format/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "wdl-format" +version = "0.1.0" +license.workspace = true +edition.workspace = true +authors.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +anyhow.workspace = true +wdl-ast = { path = "../wdl-ast", version = "0.4.0" } diff --git a/wdl-format/src/format.rs b/wdl-format/src/format.rs new file mode 100644 index 00000000..9fd39695 --- /dev/null +++ b/wdl-format/src/format.rs @@ -0,0 +1,80 @@ +//! A module for formatting WDL code. + +use anyhow::bail; +use anyhow::Result; +use wdl_ast::AstNode; +use wdl_ast::AstToken; +// use wdl_ast::Comment; +use wdl_ast::Document; +// use wdl_ast::Span; +use wdl_ast::SyntaxKind; +use wdl_ast::Validator; + +/// Format the given WDL code. +pub fn format_wdl_code(code: &str) -> Result { + let parse = Document::parse(code).into_result(); + if let Err(diagnostics) = parse { + for diagnostic in diagnostics.into_iter() { + eprintln!("{}", diagnostic.message()); + } + bail!("The document is not valid, so it cannot be formatted.") + } + let document = parse.unwrap(); + let validator = Validator::default(); + match validator.validate(&document) { + Ok(_) => { + // The document is valid, so we can format it. + } + Err(diagnostics) => { + for diagnostic in diagnostics.into_iter() { + eprintln!("{}", diagnostic.message()); + } + bail!("The document is not valid, so it cannot be formatted.") + } + } + + let mut result = String::new(); + let version_statement = document.version_statement().unwrap(); + for child in version_statement.syntax().descendants_with_tokens() { + match child.kind() { + SyntaxKind::Comment => { + result.push_str(child.as_token().unwrap().text().trim()); + } + SyntaxKind::Whitespace => { + // Skip whitespace + } + SyntaxKind::VersionKeyword => { + if result.is_empty() { + result.push_str("version "); + } else { + result.push_str("\n\nversion "); + } + result.push_str(version_statement.version().as_str()); + } + SyntaxKind::Version => { + // Handled by the version keyword + } + SyntaxKind::VersionStatementNode => { + // Ignore the root node + } + _ => { + unreachable!("Unexpected syntax kind: {:?}", child.kind()); + } + } + } + + // let ast = document.ast().as_v1().unwrap(); + Ok(result) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_format_wdl_code() { + let code = "\n\n ## preamble comment \nversion 1.1\nworkflow test {}"; + let formatted = format_wdl_code(code).unwrap(); + assert_eq!(formatted, "version 1.1"); + } +} diff --git a/wdl-format/src/lib.rs b/wdl-format/src/lib.rs new file mode 100644 index 00000000..ecb4f1e5 --- /dev/null +++ b/wdl-format/src/lib.rs @@ -0,0 +1,10 @@ +//! A library for auto-formatting WDL code. + +#![warn(missing_docs)] +#![warn(rust_2018_idioms)] +#![warn(rust_2021_compatibility)] +#![warn(missing_debug_implementations)] +#![warn(clippy::missing_docs_in_private_items)] +#![warn(rustdoc::broken_intra_doc_links)] + +pub mod format;