Skip to content

Commit ac0aeb9

Browse files
authored
Merge pull request #1009 from rust-lang/output-reducer-rtk
Rewrite output reducers with RTK
2 parents 8c28212 + ae4a1a6 commit ac0aeb9

File tree

13 files changed

+168
-200
lines changed

13 files changed

+168
-200
lines changed

ui/frontend/.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ module.exports = {
7171
'editor/AceEditor.tsx',
7272
'editor/SimpleEditor.tsx',
7373
'reducers/client.ts',
74+
'reducers/crates.ts',
7475
'reducers/featureFlags.ts',
7576
'reducers/globalConfiguration.ts',
7677
'reducers/output/assembly.ts',
@@ -80,8 +81,10 @@ module.exports = {
8081
'reducers/output/gist.ts',
8182
'reducers/output/hir.ts',
8283
'reducers/output/llvmIr.ts',
84+
'reducers/output/macroExpansion.ts',
8385
'reducers/output/meta.ts',
8486
'reducers/output/mir.ts',
87+
'reducers/output/miri.ts',
8588
'reducers/output/wasm.ts',
8689
'reducers/versions.ts',
8790
'reducers/websocket.ts',

ui/frontend/.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ node_modules
2222
!editor/AceEditor.tsx
2323
!editor/SimpleEditor.tsx
2424
!reducers/client.ts
25+
!reducers/crates.ts
2526
!reducers/featureFlags.ts
2627
!reducers/globalConfiguration.ts
2728
!reducers/output/assembly.ts
@@ -31,8 +32,10 @@ node_modules
3132
!reducers/output/gist.ts
3233
!reducers/output/hir.ts
3334
!reducers/output/llvmIr.ts
35+
!reducers/output/macroExpansion.ts
3436
!reducers/output/meta.ts
3537
!reducers/output/mir.ts
38+
!reducers/output/miri.ts
3639
!reducers/output/wasm.ts
3740
!reducers/versions.ts
3841
!reducers/websocket.ts

ui/frontend/ToolsMenu.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import MenuGroup from './MenuGroup';
66
import MenuAside from './MenuAside';
77

88
import * as selectors from './selectors';
9-
import * as actions from './actions';
109
import { useAppDispatch } from './configureStore';
1110
import { performFormat } from './reducers/output/format';
1211
import { performClippy } from './reducers/output/clippy';
12+
import { performMiri } from './reducers/output/miri';
13+
import { performMacroExpansion } from './reducers/output/macroExpansion';
1314

1415
interface ToolsMenuProps {
1516
close: () => void;
@@ -31,15 +32,15 @@ const ToolsMenu: React.FC<ToolsMenuProps> = props => {
3132
props.close();
3233
}, [dispatch, props]);
3334
const miri = useCallback(() => {
34-
dispatch(actions.performMiri());
35+
dispatch(performMiri());
3536
props.close();
3637
}, [dispatch, props]);
3738
const format = useCallback(() => {
3839
dispatch(performFormat());
3940
props.close();
4041
}, [dispatch, props]);
4142
const expandMacros = useCallback(() => {
42-
dispatch(actions.performMacroExpansion());
43+
dispatch(performMacroExpansion());
4344
props.close();
4445
}, [dispatch, props]);
4546

ui/frontend/actions.ts

Lines changed: 0 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import fetch from 'isomorphic-fetch';
22
import { ThunkAction as ReduxThunkAction, AnyAction } from '@reduxjs/toolkit';
33

44
import {
5-
codeSelector,
65
getCrateType,
76
runAsTest,
87
wasmLikelyToWork,
@@ -26,7 +25,6 @@ import {
2625
ProcessAssembly,
2726
Position,
2827
makePosition,
29-
Crate,
3028
} from './types';
3129

3230
import { performCommonExecute, wsExecuteRequest } from './reducers/output/execute';
@@ -83,14 +81,6 @@ export enum ActionType {
8381
EnableFeatureGate = 'ENABLE_FEATURE_GATE',
8482
GotoPosition = 'GOTO_POSITION',
8583
SelectText = 'SELECT_TEXT',
86-
RequestMiri = 'REQUEST_MIRI',
87-
MiriSucceeded = 'MIRI_SUCCEEDED',
88-
MiriFailed = 'MIRI_FAILED',
89-
RequestMacroExpansion = 'REQUEST_MACRO_EXPANSION',
90-
MacroExpansionSucceeded = 'MACRO_EXPANSION_SUCCEEDED',
91-
MacroExpansionFailed = 'MACRO_EXPANSION_FAILED',
92-
RequestCratesLoad = 'REQUEST_CRATES_LOAD',
93-
CratesLoadSucceeded = 'CRATES_LOAD_SUCCEEDED',
9484
NotificationSeen = 'NOTIFICATION_SEEN',
9585
BrowserWidthChanged = 'BROWSER_WIDTH_CHANGED',
9686
}
@@ -258,10 +248,6 @@ const performTestOnly = (): ThunkAction => (dispatch, getState) => {
258248
return dispatch(performCommonExecute(crateType, true));
259249
};
260250

261-
interface GenericApiFailure {
262-
error: string;
263-
}
264-
265251
const performCompileToNightlyHirOnly = (): ThunkAction => dispatch => {
266252
dispatch(changeChannel(Channel.Nightly));
267253
dispatch(performCompileToHirOnly());
@@ -337,107 +323,6 @@ export const gotoPosition = (line: string | number, column: string | number) =>
337323
export const selectText = (start: Position, end: Position) =>
338324
createAction(ActionType.SelectText, { start, end });
339325

340-
interface GeneralSuccess {
341-
stdout: string;
342-
stderr: string;
343-
}
344-
345-
const requestMiri = () =>
346-
createAction(ActionType.RequestMiri);
347-
348-
interface MiriRequestBody {
349-
code: string;
350-
edition: string;
351-
}
352-
353-
interface MiriResponseBody {
354-
success: boolean;
355-
stdout: string;
356-
stderr: string;
357-
}
358-
359-
type MiriSuccess = GeneralSuccess;
360-
361-
const receiveMiriSuccess = ({ stdout, stderr }: MiriSuccess) =>
362-
createAction(ActionType.MiriSucceeded, { stdout, stderr });
363-
364-
const receiveMiriFailure = ({ error }: GenericApiFailure) =>
365-
createAction(ActionType.MiriFailed, { error });
366-
367-
export function performMiri(): ThunkAction {
368-
// TODO: Check a cache
369-
return function(dispatch, getState) {
370-
dispatch(requestMiri());
371-
372-
const state = getState();
373-
const code = codeSelector(state);
374-
const { configuration: {
375-
edition,
376-
} } = state;
377-
const body: MiriRequestBody = { code, edition };
378-
379-
return jsonPost<MiriResponseBody>(routes.miri, body)
380-
.then(json => dispatch(receiveMiriSuccess(json)))
381-
.catch(json => dispatch(receiveMiriFailure(json)));
382-
};
383-
}
384-
385-
const requestMacroExpansion = () =>
386-
createAction(ActionType.RequestMacroExpansion);
387-
388-
interface MacroExpansionRequestBody {
389-
code: string;
390-
edition: string;
391-
}
392-
393-
interface MacroExpansionResponseBody {
394-
success: boolean;
395-
stdout: string;
396-
stderr: string;
397-
}
398-
399-
type MacroExpansionSuccess = GeneralSuccess;
400-
401-
const receiveMacroExpansionSuccess = ({ stdout, stderr }: MacroExpansionSuccess) =>
402-
createAction(ActionType.MacroExpansionSucceeded, { stdout, stderr });
403-
404-
const receiveMacroExpansionFailure = ({ error }: GenericApiFailure) =>
405-
createAction(ActionType.MacroExpansionFailed, { error });
406-
407-
export function performMacroExpansion(): ThunkAction {
408-
// TODO: Check a cache
409-
return function(dispatch, getState) {
410-
dispatch(requestMacroExpansion());
411-
412-
const state = getState();
413-
const code = codeSelector(state);
414-
const { configuration: {
415-
edition,
416-
} } = state;
417-
const body: MacroExpansionRequestBody = { code, edition };
418-
419-
return jsonPost<MacroExpansionResponseBody>(routes.macroExpansion, body)
420-
.then(json => dispatch(receiveMacroExpansionSuccess(json)))
421-
.catch(json => dispatch(receiveMacroExpansionFailure(json)));
422-
};
423-
}
424-
425-
const requestCratesLoad = () =>
426-
createAction(ActionType.RequestCratesLoad);
427-
428-
const receiveCratesLoadSuccess = ({ crates }: { crates: Crate[] }) =>
429-
createAction(ActionType.CratesLoadSucceeded, { crates });
430-
431-
export function performCratesLoad(): ThunkAction {
432-
return function(dispatch) {
433-
dispatch(requestCratesLoad());
434-
435-
return jsonGet(routes.meta.crates)
436-
.then(json => dispatch(receiveCratesLoadSuccess(json)));
437-
// TODO: Failure case
438-
};
439-
}
440-
441326
const notificationSeen = (notification: Notification) =>
442327
createAction(ActionType.NotificationSeen, { notification });
443328

@@ -557,14 +442,6 @@ export type Action =
557442
| ReturnType<typeof enableFeatureGate>
558443
| ReturnType<typeof gotoPosition>
559444
| ReturnType<typeof selectText>
560-
| ReturnType<typeof requestMiri>
561-
| ReturnType<typeof receiveMiriSuccess>
562-
| ReturnType<typeof receiveMiriFailure>
563-
| ReturnType<typeof requestMacroExpansion>
564-
| ReturnType<typeof receiveMacroExpansionSuccess>
565-
| ReturnType<typeof receiveMacroExpansionFailure>
566-
| ReturnType<typeof requestCratesLoad>
567-
| ReturnType<typeof receiveCratesLoadSuccess>
568445
| ReturnType<typeof notificationSeen>
569446
| ReturnType<typeof browserWidthChanged>
570447
| ReturnType<typeof wsExecuteRequest>

ui/frontend/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
gotoPosition,
1515
selectText,
1616
addImport,
17-
performCratesLoad,
1817
reExecuteWithBacktrace,
1918
browserWidthChanged,
2019
} from './actions';
@@ -27,6 +26,7 @@ import { disableSyncChangesToStorage } from './reducers/globalConfiguration';
2726
import Router from './Router';
2827
import configureStore from './configureStore';
2928
import { performVersionsLoad } from './reducers/versions';
29+
import { performCratesLoad } from './reducers/crates';
3030

3131
const store = configureStore(window);
3232

ui/frontend/reducers/crates.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
1+
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
12
import { sortBy } from 'lodash-es';
3+
import * as z from 'zod';
24

3-
import { Action, ActionType } from '../actions';
5+
import { adaptFetchError, jsonGet, routes } from '../actions';
46
import { Crate } from '../types';
57

6-
const DEFAULT: State = [];
8+
const sliceName = 'crates';
9+
10+
const initialState: State = [];
711

812
export type State = Crate[];
913

10-
export default function crates(state = DEFAULT, action: Action) {
11-
switch (action.type) {
12-
case ActionType.CratesLoadSucceeded:
13-
return sortBy(action.crates, c => c.name);
14-
default:
15-
return state;
16-
}
17-
}
14+
const CratesResponse = z.object({
15+
crates: Crate.array(),
16+
});
17+
type CratesResponse = z.infer<typeof CratesResponse>;
18+
19+
export const performCratesLoad = createAsyncThunk(sliceName, async () => {
20+
const d = await adaptFetchError(() => jsonGet(routes.meta.crates));
21+
const crates = await CratesResponse.parseAsync(d);
22+
return sortBy(crates.crates, (c) => c.name);
23+
});
24+
25+
const slice = createSlice({
26+
name: sliceName,
27+
initialState,
28+
reducers: {},
29+
extraReducers: (builder) => {
30+
builder.addCase(performCratesLoad.fulfilled, (_state, action) => {
31+
return action.payload;
32+
});
33+
},
34+
});
35+
36+
export default slice.reducer;

ui/frontend/reducers/output/gist.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import { jsonGet, jsonPost, routes } from '../../actions';
44
import { baseUrlSelector, codeSelector } from '../../selectors';
55
import RootState from '../../state';
66
import { Channel, Edition, Mode } from '../../types';
7-
import { RequestsInProgress } from './sharedStateManagement';
87

98
const sliceName = 'output/gist';
109

1110
const initialState: State = {
1211
requestsInProgress: 0,
1312
};
1413

15-
interface State extends RequestsInProgress {
14+
interface State {
15+
requestsInProgress: number;
1616
id?: string;
1717
url?: string;
1818
code?: string;
Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import { Action, ActionType } from '../../actions';
2-
import { finish, start } from './sharedStateManagement';
1+
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
2+
import * as z from 'zod';
33

4-
const DEFAULT: State = {
4+
import { adaptFetchError, jsonPost, routes } from '../../actions';
5+
import { macroExpansionRequestSelector } from '../../selectors';
6+
import RootState from '../../state';
7+
8+
const sliceName = 'output/macroExpansion';
9+
10+
const initialState: State = {
511
requestsInProgress: 0,
612
};
713

@@ -12,17 +18,47 @@ interface State {
1218
error?: string;
1319
}
1420

15-
export default function macroExpansion(state = DEFAULT, action: Action) {
16-
switch (action.type) {
17-
case ActionType.RequestMacroExpansion:
18-
return start(DEFAULT, state);
19-
case ActionType.MacroExpansionSucceeded: {
20-
const { stdout = '', stderr = '' } = action;
21-
return finish(state, { stdout, stderr });
22-
}
23-
case ActionType.MacroExpansionFailed:
24-
return finish(state, { error: action.error });
25-
default:
26-
return state;
27-
}
21+
interface MacroExpansionRequestBody {
22+
code: string;
23+
edition: string;
2824
}
25+
26+
const MacroExpansionResponseBody = z.object({
27+
success: z.boolean(),
28+
stdout: z.string(),
29+
stderr: z.string(),
30+
});
31+
32+
type MacroExpansionResponseBody = z.infer<typeof MacroExpansionResponseBody>;
33+
34+
export const performMacroExpansion = createAsyncThunk<
35+
MacroExpansionResponseBody,
36+
void,
37+
{ state: RootState }
38+
>(sliceName, async (_arg: void, { getState }) => {
39+
const body: MacroExpansionRequestBody = macroExpansionRequestSelector(getState());
40+
41+
const d = await adaptFetchError(() => jsonPost(routes.macroExpansion, body));
42+
return MacroExpansionResponseBody.parseAsync(d);
43+
});
44+
45+
const slice = createSlice({
46+
name: sliceName,
47+
initialState,
48+
reducers: {},
49+
extraReducers: (builder) => {
50+
builder
51+
.addCase(performMacroExpansion.pending, (state) => {
52+
state.requestsInProgress += 1;
53+
})
54+
.addCase(performMacroExpansion.fulfilled, (state, action) => {
55+
state.requestsInProgress -= 1;
56+
Object.assign(state, action.payload);
57+
})
58+
.addCase(performMacroExpansion.rejected, (state) => {
59+
state.requestsInProgress -= 1;
60+
});
61+
},
62+
});
63+
64+
export default slice.reducer;

0 commit comments

Comments
 (0)