Skip to content

Commit

Permalink
[WIP]feat: new wdl-format crate
Browse files Browse the repository at this point in the history
  • Loading branch information
a-frantz committed Jul 3, 2024
1 parent 3f502ad commit a961355
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[workspace]
members = [
"wdl",
"wdl-ast",
"wdl-ast", "wdl-format",
"wdl-gauntlet",
"wdl-grammar",
"wdl-lint",
Expand Down
12 changes: 12 additions & 0 deletions wdl-format/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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" }
80 changes: 80 additions & 0 deletions wdl-format/src/format.rs
Original file line number Diff line number Diff line change
@@ -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<String> {
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");
}
}
10 changes: 10 additions & 0 deletions wdl-format/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit a961355

Please sign in to comment.