From 0c022ea7dbef7f509d58b62a77a2abbb4d5ecd68 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Sun, 26 Jan 2020 13:46:18 +0900 Subject: [PATCH 1/7] add react-rnd to dependencies --- ui/frontend/package.json | 1 + ui/frontend/yarn.lock | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ui/frontend/package.json b/ui/frontend/package.json index 082cb5e72..bf48e8011 100644 --- a/ui/frontend/package.json +++ b/ui/frontend/package.json @@ -20,6 +20,7 @@ "react-portal": "^4.1.4", "react-prism": "^4.0.0", "react-redux": "^7.0.0", + "react-rnd": "^10.1.4", "redux": "^4.0.0", "redux-thunk": "^2.1.0", "regenerator-runtime": "^0.13.2", diff --git a/ui/frontend/yarn.lock b/ui/frontend/yarn.lock index ad1261ef4..8df129318 100644 --- a/ui/frontend/yarn.lock +++ b/ui/frontend/yarn.lock @@ -2023,6 +2023,11 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +classnames@^2.2.5: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== + clean-css@4.2.x: version "4.2.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17" @@ -3068,6 +3073,11 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-memoize@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/fast-memoize/-/fast-memoize-2.5.1.tgz#c3519241e80552ce395e1a32dcdde8d1fd680f5d" + integrity sha512-xdmw296PCL01tMOXx9mdJSmWY29jQgxyuZdq0rEHMu+Tpe1eOEtCycoG6chzlcrWsNgpZP7oL8RiQr7+G6Bl6g== + fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -5985,7 +5995,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.3" -prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -6114,6 +6124,13 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +re-resizable@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/re-resizable/-/re-resizable-6.1.1.tgz#7ff7cfe92c0b9d8b0bceaa578aadaeeff8931eaf" + integrity sha512-ngzX5xbXi9LlIghJUYZaBDkJUIMLYqO3tQ2cJZoNprCRGhfHnbyufKm51MZRIOBlLigLzPPFKBxQE8ZLezKGfA== + dependencies: + fast-memoize "^2.5.1" + react-copy-to-clipboard@^5.0.1: version "5.0.2" resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.2.tgz#d82a437e081e68dfca3761fbd57dbf2abdda1316" @@ -6132,6 +6149,14 @@ react-dom@^16.8.6: prop-types "^15.6.2" scheduler "^0.18.0" +react-draggable@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.2.0.tgz#40cc5209082ca7d613104bf6daf31372cc0e1114" + integrity sha512-5wFq//gEoeTYprnd4ze8GrFc+Rbnx+9RkOMR3vk4EbWxj02U6L6T3yrlKeiw4X5CtjD2ma2+b3WujghcXNRzkw== + dependencies: + classnames "^2.2.5" + prop-types "^15.6.0" + react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0: version "16.12.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" @@ -6174,6 +6199,15 @@ react-redux@^7.0.0: prop-types "^15.7.2" react-is "^16.9.0" +react-rnd@^10.1.4: + version "10.1.4" + resolved "https://registry.yarnpkg.com/react-rnd/-/react-rnd-10.1.4.tgz#435e30e752e4251bb1a2d618ae58e543e542ae62" + integrity sha512-m2k5jYNcqhxUfUqnzp0Dj4hfqCnGgkMrCsCDAl+jspNrkz/u3Kpj/GyKFYhPdI3CCaY+25lwfTEP3rAMbb9IxA== + dependencies: + re-resizable "6.1.1" + react-draggable "4.2.0" + tslib "1.10.0" + react@^16.8.6: version "16.12.0" resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83" @@ -7405,7 +7439,7 @@ ts-loader@^6.0.0: micromatch "^4.0.0" semver "^6.0.0" -tslib@^1.8.1, tslib@^1.9.0: +tslib@1.10.0, tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== From 8fed9c4c880fe1c7d60006660e7cdba2b467ce92 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 21:55:26 +0900 Subject: [PATCH 2/7] make resizable icon --- ui/frontend/Icon.tsx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ui/frontend/Icon.tsx b/ui/frontend/Icon.tsx index 6e44d7fa3..b4c656811 100644 --- a/ui/frontend/Icon.tsx +++ b/ui/frontend/Icon.tsx @@ -36,20 +36,26 @@ export const MoreOptionsActiveIcon = () => ( ); -// M.D. 'settings', -export const ConfigIcon = () => ( - +const createConfigIcon = (size: string) => () => ( + -); +) -// M.D. 'help_outline' -export const HelpIcon = () => ( - +// M.D. 'settings', +export const ConfigIcon = createConfigIcon('15'); +export const RustfmtTomlIcon = createConfigIcon('30'); + +const createHelpIcon = (size: string) => () => ( + ); +// M.D. 'help_outline' +export const HelpIcon = createHelpIcon('18'); +export const RustfmtModalHelpIcon = createHelpIcon('24'); + export const CheckmarkIcon = () => ( From 0d52f37ccf06702376ce9adc30b498daad0a2bc8 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 21:58:41 +0900 Subject: [PATCH 3/7] create TomlEditor --- ui/frontend/TomlEditor.tsx | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 ui/frontend/TomlEditor.tsx diff --git a/ui/frontend/TomlEditor.tsx b/ui/frontend/TomlEditor.tsx new file mode 100644 index 000000000..53b86607e --- /dev/null +++ b/ui/frontend/TomlEditor.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +type TomlEditorProps = { + toml: string; + onEditCode: (_: string) => any; +} + +class TomlEditor extends React.PureComponent { + private _editor: HTMLTextAreaElement; + + private onChange = e => this.props.onEditCode(e.target.value); + private trackEditor = component => this._editor = component; + + public render() { + return ( + + ); + } +} + +export default TomlEditor; \ No newline at end of file From 588cd8d46ce25379664e9fcd469364bb6a7a0c40 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 21:59:49 +0900 Subject: [PATCH 4/7] add actions, selectors and reducers about rustfmt --- ui/frontend/actions.ts | 11 +++++++++++ ui/frontend/reducers/index.ts | 2 ++ ui/frontend/reducers/rustfmt.ts | 26 ++++++++++++++++++++++++++ ui/frontend/selectors/index.ts | 4 +++- 4 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ui/frontend/reducers/rustfmt.ts diff --git a/ui/frontend/actions.ts b/ui/frontend/actions.ts index 0b58b9b1c..9f77bc694 100644 --- a/ui/frontend/actions.ts +++ b/ui/frontend/actions.ts @@ -87,6 +87,8 @@ export enum ActionType { CompileWasmSucceeded = 'COMPILE_WASM_SUCCEEDED', CompileWasmFailed = 'COMPILE_WASM_FAILED', EditCode = 'EDIT_CODE', + EditRustfmtToml = 'EDIT_RUSTFMT_TOML', + ToggleRustfmtTomlModalShow = 'TOGGLE_RUSTFMT_TOML_MODAL_SHOW', AddMainFunction = 'ADD_MAIN_FUNCTION', EnableFeatureGate = 'ENABLE_FEATURE_GATE', GotoPosition = 'GOTO_POSITION', @@ -415,6 +417,12 @@ export const performCompileToNightlyWasm = export const editCode = (code: string) => createAction(ActionType.EditCode, { code }); +export const editRustfmtToml = (code: string) => + createAction(ActionType.EditRustfmtToml, { code }); + +export const toggleRustfmtTomlModalShow = () => + createAction(ActionType.ToggleRustfmtTomlModalShow); + export const addMainFunction = () => createAction(ActionType.AddMainFunction); @@ -429,6 +437,7 @@ const requestFormat = () => interface FormatRequestBody { code: string; + rustfmtToml: string; edition: string; } @@ -750,6 +759,8 @@ export type Action = | ReturnType | ReturnType | ReturnType + | ReturnType + | ReturnType | ReturnType | ReturnType | ReturnType diff --git a/ui/frontend/reducers/index.ts b/ui/frontend/reducers/index.ts index 4f89407e7..e7a31f77e 100644 --- a/ui/frontend/reducers/index.ts +++ b/ui/frontend/reducers/index.ts @@ -8,6 +8,7 @@ import notifications from './notifications'; import output from './output'; import page from './page'; import position from './position'; +import rustfmt from './rustfmt'; import versions from './versions'; const playgroundApp = combineReducers({ @@ -19,6 +20,7 @@ const playgroundApp = combineReducers({ output, page, position, + rustfmt, versions, }); diff --git a/ui/frontend/reducers/rustfmt.ts b/ui/frontend/reducers/rustfmt.ts new file mode 100644 index 000000000..602dd656d --- /dev/null +++ b/ui/frontend/reducers/rustfmt.ts @@ -0,0 +1,26 @@ +import { Action, ActionType } from '../actions'; + +const DEFAULT: State = { + show: false, + toml: '', +} + +export type State = { + show: boolean; + toml: string; +}; + +export default function code(state = DEFAULT, action: Action): State { + switch (action.type) { + case ActionType.EditRustfmtToml: + return { + ...state, toml: action.code, + }; + case ActionType.ToggleRustfmtTomlModalShow: + return { + ...state, show: !state.show, + }; + default: + return state; + } +} diff --git a/ui/frontend/selectors/index.ts b/ui/frontend/selectors/index.ts index a66faa889..0c37c2084 100644 --- a/ui/frontend/selectors/index.ts +++ b/ui/frontend/selectors/index.ts @@ -6,6 +6,7 @@ import { State } from '../reducers'; import { Backtrace, Channel, Edition, PrimaryActionAuto, PrimaryActionCore } from '../types'; const codeSelector = (state: State) => state.code; +const rustfmtSelector = (state: State) => state.rustfmt.toml; const HAS_TESTS_RE = /^\s*#\s*\[\s*test\s*([^"]*)]/m; export const hasTestsSelector = createSelector(codeSelector, code => !!code.match(HAS_TESTS_RE)); @@ -274,6 +275,7 @@ export const clippyRequestSelector = createSelector( export const formatRequestSelector = createSelector( codeSelector, + rustfmtSelector, editionSelector, - (code, edition) => ({ code, edition }), + (code, rustfmtToml, edition) => ({ code, edition, rustfmtToml }), ); From e56e0369a48cd2afbd2f7f4df69ba18da3f6d491 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 22:01:03 +0900 Subject: [PATCH 5/7] add toggle to show and hide modal --- ui/frontend/ToolsMenu.tsx | 23 +++++++++++++++++------ ui/frontend/index.scss | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/ui/frontend/ToolsMenu.tsx b/ui/frontend/ToolsMenu.tsx index f329951c6..25128c7cf 100644 --- a/ui/frontend/ToolsMenu.tsx +++ b/ui/frontend/ToolsMenu.tsx @@ -1,6 +1,7 @@ import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { RustfmtTomlIcon } from './Icon'; import ButtonMenuItem from './ButtonMenuItem'; import MenuGroup from './MenuGroup'; @@ -32,15 +33,25 @@ const ToolsMenu: React.SFC = props => { dispatch(actions.performFormat()); props.close(); }, [dispatch, props]); + const formatDialog = useCallback(() => { + dispatch(actions.toggleRustfmtTomlModalShow()); + }, [dispatch]); return ( - -
Format this code with Rustfmt.
-
{rustfmtVersion} ({rustfmtVersionDetails})
- +
+ +
Format this code with Rustfmt.
+
{rustfmtVersion} ({rustfmtVersionDetails})
+
+ +
+ +
+
+ diff --git a/ui/frontend/index.scss b/ui/frontend/index.scss index c54ba016c..0c02c21cd 100644 --- a/ui/frontend/index.scss +++ b/ui/frontend/index.scss @@ -627,6 +627,7 @@ $header-transition: 0.2s ease-in-out; } .menu-item { + width: 100%; margin-bottom: 1em; &:last-child { @@ -634,6 +635,25 @@ $header-transition: 0.2s ease-in-out; } } +.menu-item-wrapper { + display: flex; + width: 100%; + margin-bottom: 1em; +} + +.menu-right { + display: flex; + align-items: center; + border-left: solid $header-main-border 2px; + + svg { + cursor: pointer; + &:hover { + color: $header-tint; + } + } +} + @mixin menu-item-title { font-size: 13px; font-weight: 600; From 2b17830a471e7f979c4e96976b595d4828b43563 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 22:24:40 +0900 Subject: [PATCH 6/7] add RustfmtTomlModal --- ui/frontend/Playground.tsx | 7 ++++ ui/frontend/RustfmtTomlModal.tsx | 62 ++++++++++++++++++++++++++++++++ ui/frontend/index.scss | 32 +++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 ui/frontend/RustfmtTomlModal.tsx diff --git a/ui/frontend/Playground.tsx b/ui/frontend/Playground.tsx index c99c1a244..d28eaa81b 100644 --- a/ui/frontend/Playground.tsx +++ b/ui/frontend/Playground.tsx @@ -5,11 +5,13 @@ import Editor from './Editor'; import Header from './Header'; import Notifications from './Notifications'; import Output from './Output'; +import RustfmtTomlModal from './RustfmtTomlModal'; import * as selectors from './selectors'; import State from './state'; const Playground: React.SFC = () => { const showNotifications = useSelector(selectors.anyNotificationsToShowSelector); + const showRustfmtTomlModal = useSelector((state: State) => state.rustfmt.show); const focus = useSelector((state: State) => state.output.meta.focus); const splitOrientation = useSelector((state: State) => state.configuration.orientation); @@ -17,6 +19,10 @@ const Playground: React.SFC = () => { const splitClass = 'playground-split'; const orientation = splitClass + '-' + splitOrientation; + const rustfmtModal = showRustfmtTomlModal + ? + : null + return (
@@ -33,6 +39,7 @@ const Playground: React.SFC = () => {
{showNotifications && } + {rustfmtModal} ); }; diff --git a/ui/frontend/RustfmtTomlModal.tsx b/ui/frontend/RustfmtTomlModal.tsx new file mode 100644 index 000000000..ee2ad573c --- /dev/null +++ b/ui/frontend/RustfmtTomlModal.tsx @@ -0,0 +1,62 @@ +import React, { useCallback } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +import { Rnd } from 'react-rnd'; + +import * as actions from './actions'; +import { Close as CloseIcon, RustfmtModalHelpIcon } from './Icon'; + +import TomlEditor from './TomlEditor'; +import State from './state'; + +const ModalDefaultWidth = 320; +const ModalDefaultHeight = 200; +const DefaultState = { + x: (window.innerWidth / 2) - ModalDefaultWidth, + y: (window.innerHeight / 2) - ModalDefaultHeight, + width: ModalDefaultWidth, + height: ModalDefaultHeight, +}; + +const RustfmtTomlModal: React.SFC = () => { + const toml = useSelector((state: State) => state.rustfmt.toml); + const dispatch = useDispatch(); + + const onEditRustfmt = useCallback((c) => dispatch(actions.editRustfmtToml(c)), [dispatch]); + const formatDialog = useCallback(() => { + dispatch(actions.toggleRustfmtTomlModalShow()); + }, [dispatch]); + + const Close = + + return ( + +
+
+
rustfmt.toml
+
+ + {Close} +
+
+ +
+
+ ); +}; + +const HelpIcon: React.SFC = () => ( + + + +); + +export default RustfmtTomlModal; diff --git a/ui/frontend/index.scss b/ui/frontend/index.scss index 0c02c21cd..5d9711695 100644 --- a/ui/frontend/index.scss +++ b/ui/frontend/index.scss @@ -914,3 +914,35 @@ $header-transition: 0.2s ease-in-out; cursor: pointer; } } + +.rustfmt-modal { + border: 4px solid $border-color; + z-index: 10; + + .backbone { + height: 100%; + } + + .toml-header { + display: flex; + justify-content: space-between; + line-height: 30px; + background-color: $background; + + .toml-header-label { + margin-left: 4px; + } + + .icon-areas { + display: flex; + padding: 4px; + } + } + + .toml-input-area { + width: 100%; + height: calc(100% - 30px); + resize: none; + border: none; + } +} From ba9477d1bc643feb0fa2d9769a3dd10fa701a9c8 Mon Sep 17 00:00:00 2001 From: rchaser53 Date: Wed, 29 Jan 2020 23:04:35 +0900 Subject: [PATCH 7/7] mount rustfmt.toml --- ui/src/main.rs | 3 +++ ui/src/sandbox.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/ui/src/main.rs b/ui/src/main.rs index 9a75acb03..e82c7b1aa 100644 --- a/ui/src/main.rs +++ b/ui/src/main.rs @@ -576,6 +576,8 @@ struct ExecuteResponse { #[derive(Debug, Clone, Deserialize)] struct FormatRequest { code: String, + #[serde(rename = "rustfmtToml")] + rustfmt_toml: String, #[serde(default)] edition: String, } @@ -748,6 +750,7 @@ impl TryFrom for sandbox::FormatRequest { fn try_from(me: FormatRequest) -> Result { Ok(sandbox::FormatRequest { code: me.code, + rustfmt_toml: me.rustfmt_toml, edition: parse_edition(&me.edition)?, }) } diff --git a/ui/src/sandbox.rs b/ui/src/sandbox.rs index f8efd2ee9..3d9f2b165 100644 --- a/ui/src/sandbox.rs +++ b/ui/src/sandbox.rs @@ -83,6 +83,7 @@ pub struct Sandbox { #[allow(dead_code)] scratch: TempDir, input_file: PathBuf, + rustfmt_toml: PathBuf, output_dir: PathBuf, } @@ -104,6 +105,7 @@ impl Sandbox { pub fn new() -> Result { let scratch = TempDir::new("playground").context(UnableToCreateTempDir)?; let input_file = scratch.path().join("input.rs"); + let rustfmt_toml = scratch.path().join("rustfmt.toml"); let output_dir = scratch.path().join("output"); fs::create_dir(&output_dir).context(UnableToCreateOutputDir)?; @@ -112,6 +114,7 @@ impl Sandbox { Ok(Sandbox { scratch, input_file, + rustfmt_toml, output_dir, }) } @@ -184,6 +187,7 @@ impl Sandbox { pub fn format(&self, req: &FormatRequest) -> Result { self.write_source_code(&req.code)?; + self.write_rustfmt_toml(&req.rustfmt_toml)?; let command = self.format_command(req); let output = run_command_with_timeout(command)?; @@ -301,6 +305,14 @@ impl Sandbox { Ok(()) } + fn write_rustfmt_toml(&self, code: &str) -> Result<()> { + fs::write(&self.rustfmt_toml, code).context(UnableToCreateSourceFile)?; + fs::set_permissions(&self.rustfmt_toml, wide_open_permissions()).context(UnableToSetSourcePermissions)?; + + log::debug!("Wrote {} bytes of source to rustfmt.toml", code.len()); + Ok(()) + } + fn compile_command(&self, target: CompileTarget, channel: Channel, mode: Mode, tests: bool, req: impl CrateTypeRequest + EditionRequest + BacktraceRequest) -> Command { let mut cmd = self.docker_command(Some(req.crate_type())); set_execution_environment(&mut cmd, Some(target), &req); @@ -373,6 +385,10 @@ impl Sandbox { mount_input_file.push("/playground/"); mount_input_file.push(crate_type.file_name()); + let mut mount_rustfmt = self.rustfmt_toml.as_os_str().to_os_string(); + mount_rustfmt.push(":"); + mount_rustfmt.push("/playground/rustfmt.toml"); + let mut mount_output_dir = self.output_dir.as_os_str().to_os_string(); mount_output_dir.push(":"); mount_output_dir.push("/playground-result"); @@ -381,6 +397,7 @@ impl Sandbox { cmd .arg("--volume").arg(&mount_input_file) + .arg("--volume").arg(&mount_rustfmt) .arg("--volume").arg(&mount_output_dir); cmd @@ -746,6 +763,7 @@ pub struct ExecuteResponse { #[derive(Debug, Clone)] pub struct FormatRequest { pub code: String, + pub rustfmt_toml: String, pub edition: Option, } @@ -1119,6 +1137,7 @@ mod test { fn formatting_code() { let req = FormatRequest { code: "fn foo () { method_call(); }".to_string(), + rustfmt_toml: "".to_string(), edition: None, }; @@ -1134,13 +1153,25 @@ mod test { // Code that is only syntactically valid in Rust 2018 const FORMAT_IN_EDITION_2018: &str = r#"fn main() { use std::num::ParseIntError; let result: Result = try { "1".parse::()? + "2".parse::()? + "3".parse::()? }; assert_eq!(result, Ok(6)); }"#; - + const FORMAT_USING_RUSTFMT_TOML: &str = r#"fn main() { + let lorem = vec![ + "ipsum", + "dolor", + "sit", + "amet", + "consectetur", + "adipiscing", + "elit", + ]; +} + "#; const FORMAT_ERROR: &str = r#"error: expected identifier, found `"1"`"#; #[test] fn formatting_code_edition_2015() -> Result<()> { let req = FormatRequest { code: FORMAT_IN_EDITION_2018.to_string(), + rustfmt_toml: "".to_string(), edition: Some(Edition::Rust2015), }; @@ -1154,6 +1185,7 @@ mod test { fn formatting_code_edition_2018() -> Result<()> { let req = FormatRequest { code: FORMAT_IN_EDITION_2018.to_string(), + rustfmt_toml: "".to_string(), edition: Some(Edition::Rust2018), }; @@ -1170,6 +1202,30 @@ mod test { Ok(()) } + #[test] + fn formatting_code_using_rustfmt_toml() -> Result<()> { + let req = FormatRequest { + code: FORMAT_USING_RUSTFMT_TOML.to_string(), + rustfmt_toml: r#"indent_style = "Visual""#.to_string(), + edition: Some(Edition::Rust2018), + }; + + let resp = Sandbox::new()?.format(&req)?; + assert!(!resp.stderr.contains(FORMAT_ERROR)); + + let lines: Vec<_> = resp.code.lines().collect(); + assert_eq!(lines[0], r#"fn main() {"#); + assert_eq!(lines[1], r#" let lorem = vec!["ipsum","#); + assert_eq!(lines[2], r#" "dolor","#); + assert_eq!(lines[3], r#" "sit","#); + assert_eq!(lines[4], r#" "amet","#); + assert_eq!(lines[5], r#" "consectetur","#); + assert_eq!(lines[6], r#" "adipiscing","#); + assert_eq!(lines[7], r#" "elit",];"#); + assert_eq!(lines[8], r#"}"#); + Ok(()) + } + #[test] fn linting_code() { let code = r#"