diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 047e994..82e5b86 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -43,34 +43,37 @@ jobs: steps: - uses: actions/checkout@v4 - uses: Swatinem/rust-cache@v2 - # Used by gleam format, mix format + # gleam_format, mix_format # NOTE: should be first since it is sometimes crashes (?) - uses: erlef/setup-beam@v1 with: otp-version: "26" gleam-version: "1.0.0" elixir-version: "1.16.1" - # Used by ruff + # ruff - uses: actions/setup-python@v5 with: cache: "pip" - # Used by biome + # biome, prettier, stylua - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} - # Used by nimpretty + # nimpretty - uses: jiro4989/setup-nim-action@v1 - # Used by zigfmt + # zigfmt - uses: goto-bus-stop/setup-zig@v2 + # taplo - uses: uncenter/setup-taplo@v1 - # Used go shfmt + # shfmt, gofmt, gofumpt - uses: actions/setup-go@v5 with: go-version: "stable" - # Used by rubocop + # rubocop - uses: ruby/setup-ruby@v1 with: ruby-version: "3.3" + # dart_format + - uses: dart-lang/setup-dart@v1 - run: rustup toolchain install stable --profile minimal - run: rustup component add rustfmt clippy diff --git a/README.md b/README.md index d127018..794224d 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ mdsf init | Language | Formatters | | ---------- | ------------------- | | CSS | `prettier` | +| Dart | `dart_format` | | Elixir | `mix_format` | | Go | `gofmt`, `gofumpt` | | Gleam | `gleam_format` | diff --git a/schemas/v0.0.0/mdsf.schema.json b/schemas/v0.0.0/mdsf.schema.json index 97a570a..8f793b9 100644 --- a/schemas/v0.0.0/mdsf.schema.json +++ b/schemas/v0.0.0/mdsf.schema.json @@ -14,6 +14,17 @@ } ] }, + "dart": { + "default": { + "enabled": true, + "formatter": "dart_format" + }, + "allOf": [ + { + "$ref": "#/definitions/Dart" + } + ] + }, "elixir": { "default": { "enabled": true, @@ -235,6 +246,27 @@ "type": "string", "enum": ["prettier"] }, + "Dart": { + "type": "object", + "properties": { + "enabled": { + "default": true, + "type": "boolean" + }, + "formatter": { + "default": "dart_format", + "allOf": [ + { + "$ref": "#/definitions/DartFormatter" + } + ] + } + } + }, + "DartFormatter": { + "type": "string", + "enum": ["dart_format"] + }, "Elixir": { "type": "object", "properties": { diff --git a/src/config.rs b/src/config.rs index 44a56ec..3814781 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,9 +1,9 @@ use schemars::JsonSchema; use crate::languages::{ - css::Css, elixir::Elixir, gleam::Gleam, go::Go, html::Html, javascript::JavaScript, json::Json, - lua::Lua, markdown::Markdown, nim::Nim, python::Python, ruby::Ruby, rust::Rust, shell::Shell, - toml::Toml, typescript::TypeScript, vue::Vue, yaml::Yaml, zig::Zig, + css::Css, dart::Dart, elixir::Elixir, gleam::Gleam, go::Go, html::Html, javascript::JavaScript, + json::Json, lua::Lua, markdown::Markdown, nim::Nim, python::Python, ruby::Ruby, rust::Rust, + shell::Shell, toml::Toml, typescript::TypeScript, vue::Vue, yaml::Yaml, zig::Zig, }; #[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] @@ -15,6 +15,9 @@ pub struct MdsfConfig { #[serde(default)] pub css: Css, + #[serde(default)] + pub dart: Dart, + #[serde(default)] pub elixir: Elixir, @@ -76,6 +79,7 @@ impl Default for MdsfConfig { Self { schema: default_schema_location(), css: Css::default(), + dart: Dart::default(), elixir: Elixir::default(), go: Go::default(), gleam: Gleam::default(), diff --git a/src/formatters/dart_format.rs b/src/formatters/dart_format.rs new file mode 100644 index 0000000..bf296f4 --- /dev/null +++ b/src/formatters/dart_format.rs @@ -0,0 +1,39 @@ +use super::execute_command; + +#[inline] +pub fn format_using_dart_format( + snippet_path: &std::path::Path, +) -> std::io::Result<(bool, Option)> { + let mut cmd = std::process::Command::new("dart"); + + cmd.arg("format").arg(snippet_path); + + execute_command(&mut cmd, snippet_path) +} + +#[cfg(test)] +mod test_dart_format { + use crate::{formatters::setup_snippet, languages::Language}; + + #[test] + fn it_should_format_dart() { + let input = "class Adder { int add(int a, int b) { return a + b; } } "; + + let expected_output = "class Adder { + int add(int a, int b) { + return a + b; + } +} +"; + + let snippet = setup_snippet(input, Language::Dart.to_file_ext()) + .expect("it to create a snippet file"); + + let output = super::format_using_dart_format(snippet.path()) + .expect("it to be successful") + .1 + .expect("it to be some"); + + assert_eq!(expected_output, output); + } +} diff --git a/src/formatters/mod.rs b/src/formatters/mod.rs index ee29624..fa86290 100644 --- a/src/formatters/mod.rs +++ b/src/formatters/mod.rs @@ -11,6 +11,7 @@ use crate::{ }; pub mod biome; +pub mod dart_format; pub mod gleam_format; pub mod gofmt; pub mod gofumpt; @@ -87,6 +88,7 @@ pub fn format_snippet(config: &MdsfConfig, language: &Language, code: &str) -> S if let Ok(Some(formatted_code)) = match language { Language::Css => config.css.format(snippet_path), + Language::Dart => config.dart.format(snippet_path), Language::Elixir => config.elixir.format(snippet_path), Language::Go => config.go.format(snippet_path), Language::Gleam => config.gleam.format(snippet_path), diff --git a/src/languages/dart.rs b/src/languages/dart.rs new file mode 100644 index 0000000..2919509 --- /dev/null +++ b/src/languages/dart.rs @@ -0,0 +1,43 @@ +use schemars::JsonSchema; + +use crate::{config::default_enabled, formatters::dart_format::format_using_dart_format}; + +use super::LanguageFormatter; + +#[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)] +pub enum DartFormatter { + #[default] + #[serde(rename = "dart_format")] + DartFormat, +} + +#[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)] +pub struct Dart { + #[serde(default = "default_enabled")] + pub enabled: bool, + #[serde(default)] + pub formatter: DartFormatter, +} + +impl Default for Dart { + #[inline] + fn default() -> Self { + Self { + enabled: true, + formatter: DartFormatter::default(), + } + } +} + +impl LanguageFormatter for Dart { + #[inline] + fn format(&self, snippet_path: &std::path::Path) -> std::io::Result> { + if !self.enabled { + return Ok(None); + } + + match self.formatter { + DartFormatter::DartFormat => format_using_dart_format(snippet_path).map(|res| res.1), + } + } +} diff --git a/src/languages/mod.rs b/src/languages/mod.rs index f029a4b..e0c3a03 100644 --- a/src/languages/mod.rs +++ b/src/languages/mod.rs @@ -1,5 +1,6 @@ pub enum Language { Css, + Dart, Elixir, Go, Gleam, @@ -30,7 +31,6 @@ pub enum Language { // TODO: FSharp, // TODO: Swift, // TODO: Svelte, - // TODO: Dart, // TODO: Julia, // TODO: Dockerfile, // TODO: XML, @@ -45,6 +45,7 @@ pub enum Language { } pub mod css; +pub mod dart; pub mod elixir; pub mod gleam; pub mod go; @@ -73,6 +74,7 @@ impl Language { pub fn maybe_from_str(input: &str) -> Option { match input { "css" | "scss" => Some(Self::Css), + "dart" => Some(Self::Dart), "elixir" => Some(Self::Elixir), "go" | "golang" => Some(Self::Go), "gleam" => Some(Self::Gleam), @@ -100,6 +102,7 @@ impl Language { match self { // NOTE: since scss is a superset of css we might as well support both at the same time Self::Css => ".scss", + Self::Dart => ".dart", Self::Elixir => ".ex", Self::Go => ".go", Self::Gleam => ".gleam", diff --git a/tests/dart.md b/tests/dart.md new file mode 100644 index 0000000..c0c623a --- /dev/null +++ b/tests/dart.md @@ -0,0 +1,6 @@ +```dart + + class Adder {int add(int a, int b) {return a + b;}} + + +```