Skip to content

Commit

Permalink
feat(fsharp): add support for fantomas (#128)
Browse files Browse the repository at this point in the history
Closes #110
  • Loading branch information
hougesen authored Mar 23, 2024
1 parent 3641b2e commit 602bc74
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 8 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mdsf init
| Elixir | `mix_format` |
| Elm | `elm-format` |
| Erlang | `efmt`, `erlfmt` |
| FSharp | `fantomas` |
| Gleam | `gleam_format` |
| Go | `gofmt`, `gofumpt`, `goimports` |
| GraphQL | `prettier` |
Expand Down
40 changes: 40 additions & 0 deletions schemas/v0.0.2/mdsf.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@
}
]
},
"fsharp": {
"default": {
"enabled": true,
"formatter": "fantomas"
},
"allOf": [
{
"$ref": "#/definitions/Lang_for_FSharp"
}
]
},
"gleam": {
"default": {
"enabled": true,
Expand Down Expand Up @@ -547,6 +558,10 @@
"type": "string",
"enum": ["erlfmt", "efmt"]
},
"FSharp": {
"type": "string",
"enum": ["fantomas"]
},
"Gleam": {
"type": "string",
"enum": ["gleam_format"]
Expand Down Expand Up @@ -723,6 +738,18 @@
}
}
},
"Lang_for_FSharp": {
"type": "object",
"required": ["enabled", "formatter"],
"properties": {
"enabled": {
"type": "boolean"
},
"formatter": {
"$ref": "#/definitions/MdsfFormatter_for_FSharp"
}
}
},
"Lang_for_Gleam": {
"type": "object",
"required": ["enabled", "formatter"],
Expand Down Expand Up @@ -1282,6 +1309,19 @@
}
]
},
"MdsfFormatter_for_FSharp": {
"anyOf": [
{
"$ref": "#/definitions/FSharp"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/MdsfFormatter_for_FSharp"
}
}
]
},
"MdsfFormatter_for_Gleam": {
"anyOf": [
{
Expand Down
18 changes: 11 additions & 7 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use schemars::JsonSchema;

use crate::languages::{
blade::Blade, c::C, clojure::Clojure, cpp::Cpp, crystal::Crystal, csharp::CSharp, css::Css,
dart::Dart, elixir::Elixir, elm::Elm, erlang::Erlang, gleam::Gleam, go::Go, graphql::GraphQL,
groovy::Groovy, haskell::Haskell, html::Html, java::Java, javascript::JavaScript, json::Json,
just::Just, kotlin::Kotlin, lua::Lua, markdown::Markdown, nim::Nim, objective_c::ObjectiveC,
ocaml::OCaml, perl::Perl, protobuf::Protobuf, purescript::PureScript, python::Python,
rescript::ReScript, roc::Roc, ruby::Ruby, rust::Rust, scala::Scala, shell::Shell, sql::Sql,
swift::Swift, toml::Toml, typescript::TypeScript, vue::Vue, xml::Xml, yaml::Yaml, zig::Zig,
Lang,
dart::Dart, elixir::Elixir, elm::Elm, erlang::Erlang, fsharp::FSharp, gleam::Gleam, go::Go,
graphql::GraphQL, groovy::Groovy, haskell::Haskell, html::Html, java::Java,
javascript::JavaScript, json::Json, just::Just, kotlin::Kotlin, lua::Lua, markdown::Markdown,
nim::Nim, objective_c::ObjectiveC, ocaml::OCaml, perl::Perl, protobuf::Protobuf,
purescript::PureScript, python::Python, rescript::ReScript, roc::Roc, ruby::Ruby, rust::Rust,
scala::Scala, shell::Shell, sql::Sql, swift::Swift, toml::Toml, typescript::TypeScript,
vue::Vue, xml::Xml, yaml::Yaml, zig::Zig, Lang,
};

#[derive(Debug, serde::Serialize, serde::Deserialize, JsonSchema)]
Expand Down Expand Up @@ -51,6 +51,9 @@ pub struct MdsfConfig {
#[serde(default)]
pub erlang: Lang<Erlang>,

#[serde(default)]
pub fsharp: Lang<FSharp>,

#[serde(default)]
pub gleam: Lang<Gleam>,

Expand Down Expand Up @@ -170,6 +173,7 @@ impl Default for MdsfConfig {
elixir: Lang::<Elixir>::default(),
elm: Lang::<Elm>::default(),
erlang: Lang::<Erlang>::default(),
fsharp: Lang::<FSharp>::default(),
gleam: Lang::<Gleam>::default(),
go: Lang::<Go>::default(),
graphql: Lang::<GraphQL>::default(),
Expand Down
40 changes: 40 additions & 0 deletions src/formatters/fantomas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use super::execute_command;

#[inline]
pub fn format_using_fantomas(
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
let mut cmd = std::process::Command::new("fantomas");

cmd.arg(snippet_path);

execute_command(&mut cmd, snippet_path)
}

#[cfg(test)]
mod test_fantomas {
use crate::{
formatters::{fantomas::format_using_fantomas, setup_snippet},
languages::Language,
};

#[test_with::executable(fantomas)]
#[test]
fn it_should_format_ocaml() {
let input = "
let add a b = a + b
";
let expected_output = "let add a b = a + b
";

let snippet = setup_snippet(input, Language::FSharp.to_file_ext())
.expect("it to create a snippet file");

let output = format_using_fantomas(snippet.path())
.expect("it to be successful")
.1
.expect("it to be some");

assert_eq!(expected_output, output);
}
}
2 changes: 2 additions & 0 deletions src/formatters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod deno_fmt;
pub mod efmt;
pub mod elm_format;
pub mod erlfmt;
pub mod fantomas;
pub mod fourmolu;
pub mod gleam_format;
pub mod gofmt;
Expand Down Expand Up @@ -140,6 +141,7 @@ pub fn format_snippet(config: &MdsfConfig, language: &Language, code: &str) -> S
Language::Elixir => config.elixir.format(snippet_path),
Language::Elm => config.elm.format(snippet_path),
Language::Erlang => config.erlang.format(snippet_path),
Language::FSharp => config.fsharp.format(snippet_path),
Language::Gleam => config.gleam.format(snippet_path),
Language::Go => config.go.format(snippet_path),
Language::GraphQL => config.graphql.format(snippet_path),
Expand Down
98 changes: 98 additions & 0 deletions src/languages/fsharp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use schemars::JsonSchema;

use crate::formatters::{fantomas::format_using_fantomas, MdsfFormatter};

use super::{Lang, LanguageFormatter};

#[derive(Debug, Default, serde::Serialize, serde::Deserialize, JsonSchema)]
#[cfg_attr(test, derive(PartialEq, Eq))]
pub enum FSharp {
#[default]
#[serde(rename = "fantomas")]
Fantomas,
}

impl Default for Lang<FSharp> {
#[inline]
fn default() -> Self {
Self {
enabled: true,
formatter: MdsfFormatter::<FSharp>::default(),
}
}
}

impl Default for MdsfFormatter<FSharp> {
#[inline]
fn default() -> Self {
Self::Single(FSharp::Fantomas)
}
}

impl LanguageFormatter for FSharp {
#[inline]
fn format_snippet(
&self,
snippet_path: &std::path::Path,
) -> std::io::Result<(bool, Option<String>)> {
match self {
Self::Fantomas => format_using_fantomas(snippet_path),
}
}
}

#[cfg(test)]
mod test_fsharp {
use crate::{
formatters::{setup_snippet, MdsfFormatter},
languages::Lang,
};

use super::FSharp;

const INPUT: &str = "
let add a b =
a + b
";
const EXTENSION: &str = crate::languages::Language::FSharp.to_file_ext();

#[test]
fn it_should_be_enabled_by_default() {
assert!(Lang::<FSharp>::default().enabled);
}

#[test]
fn it_should_not_format_when_enabled_is_false() {
let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file");
let snippet_path = snippet.path();

assert!(Lang::<FSharp> {
enabled: false,
formatter: MdsfFormatter::<FSharp>::default(),
}
.format(snippet_path)
.expect("it to not fail")
.is_none());
}

#[test_with::executable(fantomas)]
#[test]
fn test_fantomas() {
let l = Lang::<FSharp> {
enabled: true,
formatter: MdsfFormatter::Single(FSharp::Fantomas),
};

let snippet = setup_snippet(INPUT, EXTENSION).expect("it to save the file");
let snippet_path = snippet.path();

let output = l
.format(snippet_path)
.expect("it to not fail")
.expect("it to be a snippet");

let expected_output = "let add a b = a + b
";
assert_eq!(output, expected_output);
}
}
5 changes: 4 additions & 1 deletion src/languages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum Language {
Elixir,
Elm,
Erlang,
FSharp,
Gleam,
Go,
GraphQL,
Expand Down Expand Up @@ -49,7 +50,6 @@ pub enum Language {
Yaml,
Zig,
// TODO: PHP,
// TODO: FSharp,
// TODO: Svelte,
// TODO: Julia,
// TODO: Dockerfile,
Expand All @@ -69,6 +69,7 @@ pub mod dart;
pub mod elixir;
pub mod elm;
pub mod erlang;
pub mod fsharp;
pub mod gleam;
pub mod go;
pub mod graphql;
Expand Down Expand Up @@ -125,6 +126,7 @@ impl Language {
"elixir" => Some(Self::Elixir),
"elm" => Some(Self::Elm),
"erlang" => Some(Self::Erlang),
"fsharp" => Some(Self::FSharp),
"gleam" => Some(Self::Gleam),
"go" | "golang" => Some(Self::Go),
"graphql" | "gql" => Some(Self::GraphQL),
Expand Down Expand Up @@ -179,6 +181,7 @@ impl Language {
Self::Elixir => ".ex",
Self::Elm => ".elm",
Self::Erlang => ".erl",
Self::FSharp => ".fs",
Self::Gleam => ".gleam",
Self::Go => ".go",
Self::GraphQL => ".gql",
Expand Down

0 comments on commit 602bc74

Please sign in to comment.