Skip to content

Commit e5ab0fe

Browse files
authored
Merge pull request #138 from AY2021S1-CS2103T-T10-3/feature/69
Make commands print out something sensible when they're executed
2 parents 7954d4a + 092616d commit e5ab0fe

28 files changed

+311
-220
lines changed

src/main/java/chopchop/commons/core/Messages.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/java/chopchop/logic/commands/AddIngredientCommand.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ public class AddIngredientCommand extends Command implements Undoable {
2626
+ ARG_QUANTITY + " 3 "
2727
+ ARG_EXPIRY + " 2020-10-05";
2828

29-
public static final String MESSAGE_ADD_INGREDIENT_SUCCESS = "Ingredient added: %s";
30-
public static final String MESSAGE_COMBINE_INGREDIENT_SUCCESS = "Ingredient updated: %s";
31-
public static final String MESSAGE_UNDO_SUCCESS = "Ingredient updated: %s";
32-
3329
private final Ingredient ingredient;
3430
private Ingredient existingIngredient;
3531
private Ingredient combinedIngredient;
@@ -54,27 +50,40 @@ public CommandResult execute(Model model, HistoryManager historyManager) throws
5450
this.combinedIngredient = this.existingIngredient.combine(this.ingredient);
5551
model.setIngredient(this.existingIngredient, this.combinedIngredient);
5652

57-
return new CommandResult(String.format(MESSAGE_COMBINE_INGREDIENT_SUCCESS, this.combinedIngredient));
5853
} catch (IncompatibleIngredientsException e) {
59-
throw new CommandException(e.toString());
54+
return CommandResult.error(e.toString());
6055
}
56+
57+
return CommandResult.message("Updated ingredient '%s'", this.combinedIngredient.getName());
58+
6159
} else {
60+
6261
model.addIngredient(this.ingredient);
63-
return new CommandResult(String.format(MESSAGE_ADD_INGREDIENT_SUCCESS, this.ingredient));
62+
return CommandResult.message("Added ingredient '%s'", this.ingredient.getName());
6463
}
6564
}
6665

6766
@Override
6867
public CommandResult undo(Model model) {
6968
requireNonNull(model);
7069

70+
String action = "";
71+
Ingredient ingr = null;
72+
7173
if (this.existingIngredient == null && this.combinedIngredient == null) {
74+
7275
model.deleteIngredient(this.ingredient);
73-
return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, this.ingredient));
76+
77+
ingr = this.ingredient;
78+
action = "removed";
7479
} else {
7580
model.setIngredient(this.combinedIngredient, this.existingIngredient);
76-
return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, this.existingIngredient));
81+
82+
ingr = this.existingIngredient;
83+
action = "updated";
7784
}
85+
86+
return CommandResult.message("Undo: %s ingredient '%s'", action, ingr.getName());
7887
}
7988

8089
@Override

src/main/java/chopchop/logic/commands/AddRecipeCommand.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ public class AddRecipeCommand extends Command implements Undoable {
2828
+ ARG_STEP + " Chop tomatoes. "
2929
+ ARG_STEP + " Add sugar to it and mix well.";
3030

31-
public static final String MESSAGE_ADD_RECIPE_SUCCESS = "Recipe added: %s";
32-
public static final String MESSAGE_DUPLICATE_RECIPE = "Recipe '%s' already exists in the recipe book";
33-
public static final String MESSAGE_UNDO_SUCCESS = "Recipe removed: %s";
34-
3531
private final Recipe recipe;
3632

3733
/**
@@ -47,19 +43,19 @@ public CommandResult execute(Model model, HistoryManager historyManager) throws
4743
requireNonNull(model);
4844

4945
if (model.hasRecipe(this.recipe)) {
50-
throw new CommandException(String.format(MESSAGE_DUPLICATE_RECIPE, this.recipe.getName()));
46+
return CommandResult.error("Recipe '%s' already exists", this.recipe.getName());
5147
}
5248

5349
model.addRecipe(this.recipe);
54-
return new CommandResult(String.format(MESSAGE_ADD_RECIPE_SUCCESS, this.recipe));
50+
return CommandResult.message("Added recipe '%s'", this.recipe.getName());
5551
}
5652

5753
@Override
5854
public CommandResult undo(Model model) {
5955
requireNonNull(model);
6056

6157
model.deleteRecipe(this.recipe);
62-
return new CommandResult(String.format(MESSAGE_UNDO_SUCCESS, this.recipe));
58+
return CommandResult.message("Undo: removed recipe '%s'", this.recipe.getName());
6359
}
6460

6561
@Override

src/main/java/chopchop/logic/commands/Command.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1+
// Command.java
2+
13
package chopchop.logic.commands;
24

5+
import chopchop.commons.util.Result;
36
import chopchop.logic.commands.exceptions.CommandException;
47
import chopchop.logic.history.HistoryManager;
8+
import chopchop.logic.parser.ItemReference;
59
import chopchop.model.Model;
10+
import chopchop.model.ingredient.Ingredient;
11+
import chopchop.model.recipe.Recipe;
612

713
/**
814
* Represents a command with hidden internal logic and the ability to be executed.
915
*/
1016
public abstract class Command {
17+
1118
/**
1219
* Executes the command and returns the result message.
1320
*
@@ -17,4 +24,59 @@ public abstract class Command {
1724
* @throws CommandException If an error occurs during command execution.
1825
*/
1926
public abstract CommandResult execute(Model model, HistoryManager historyManager) throws CommandException;
27+
28+
29+
/**
30+
* Resolves the ingredient reference, or returns an error message.
31+
*
32+
* @param ref the reference to resolve
33+
* @param model the model to use
34+
* @return the found ingredient, or an error message
35+
*/
36+
public Result<Ingredient> resolveIngredientReference(ItemReference ref, Model model) {
37+
38+
if (ref.isIndexed()) {
39+
var lastShownList = model.getFilteredIngredientList();
40+
41+
if (ref.getZeroIndex() >= lastShownList.size()) {
42+
return Result.error("Ingredient index '%d' is out of range (should be between 1 and %d)",
43+
ref.getOneIndex(), lastShownList.size()
44+
);
45+
}
46+
47+
return Result.of(lastShownList.get(ref.getZeroIndex()));
48+
49+
} else {
50+
51+
return Result.ofOptional(model.findIngredientWithName(ref.getName()),
52+
String.format("No ingredient named '%s'", ref.getName()));
53+
}
54+
}
55+
56+
/**
57+
* Resolves the recipe reference, or returns an error message.
58+
*
59+
* @param ref the reference to resolve
60+
* @param model the model to use
61+
* @return the found recipe, or an error message
62+
*/
63+
public Result<Recipe> resolveRecipeReference(ItemReference ref, Model model) {
64+
65+
if (ref.isIndexed()) {
66+
var lastShownList = model.getFilteredRecipeList();
67+
68+
if (ref.getZeroIndex() >= lastShownList.size()) {
69+
return Result.error("Recipe index '%d' is out of range (should be between 1 and %d)",
70+
ref.getOneIndex(), lastShownList.size()
71+
);
72+
}
73+
74+
return Result.of(lastShownList.get(ref.getZeroIndex()));
75+
76+
} else {
77+
78+
return Result.ofOptional(model.findRecipeWithName(ref.getName()),
79+
String.format("No recipe named '%s'", ref.getName()));
80+
}
81+
}
2082
}
Lines changed: 86 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// CommandResult.java
2+
13
package chopchop.logic.commands;
24

35
import static java.util.Objects.requireNonNull;
@@ -8,54 +10,113 @@
810
* Represents the result of a command execution.
911
*/
1012
public class CommandResult {
11-
private final String feedbackToUser;
1213

13-
/** Help information should be shown to the user. */
14+
private final String message;
15+
private final boolean isError;
1416
private final boolean showHelp;
15-
16-
/** The application should exit. */
17-
private final boolean exit;
17+
private final boolean shouldExit;
1818

1919
/**
2020
* Constructs a {@code CommandResult} with the specified fields.
2121
*/
22-
public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) {
23-
this.feedbackToUser = requireNonNull(feedbackToUser);
22+
private CommandResult(String message, boolean isError, boolean shouldExit, boolean showHelp) {
23+
requireNonNull(message);
24+
25+
this.message = message;
26+
this.isError = isError;
2427
this.showHelp = showHelp;
25-
this.exit = exit;
28+
this.shouldExit = shouldExit;
2629
}
2730

2831
/**
29-
* Constructs a {@code CommandResult} with the specified {@code feedbackToUser},
30-
* and other fields set to their default value.
32+
* Returns true if the application should exit after this command
3133
*/
32-
public CommandResult(String feedbackToUser) {
33-
this(feedbackToUser, false, false);
34+
public boolean shouldExit() {
35+
return this.shouldExit;
3436
}
3537

36-
public String getFeedbackToUser() {
37-
return this.feedbackToUser;
38+
/**
39+
* Returns true if the app should open the help window
40+
*/
41+
public boolean shouldShowHelp() {
42+
return this.showHelp;
3843
}
3944

40-
public boolean isShowHelp() {
41-
return this.showHelp;
45+
/**
46+
* Returns true if the message should be styled as an error
47+
*/
48+
public boolean isError() {
49+
return this.isError;
4250
}
4351

44-
public boolean isExit() {
45-
return this.exit;
52+
/**
53+
* Returns true if !isError()
54+
*/
55+
public boolean didSucceed() {
56+
return !this.isError;
57+
}
58+
59+
/**
60+
* Returns the message
61+
*/
62+
public String getMessage() {
63+
return this.message;
4664
}
4765

4866
@Override
49-
public boolean equals(Object other) {
50-
return other == this
51-
|| (other instanceof CommandResult
52-
&& this.feedbackToUser.equals(((CommandResult) other).feedbackToUser)
53-
&& this.showHelp == ((CommandResult) other).showHelp
54-
&& this.exit == ((CommandResult) other).exit);
67+
public boolean equals(Object obj) {
68+
if (obj == this) {
69+
return true;
70+
} else if (!(obj instanceof CommandResult)) {
71+
return false;
72+
}
73+
74+
var cr = (CommandResult) obj;
75+
76+
return this.message.equals(cr.message)
77+
&& this.isError == cr.isError
78+
&& this.showHelp == cr.showHelp
79+
&& this.shouldExit == cr.shouldExit;
5580
}
5681

5782
@Override
5883
public int hashCode() {
59-
return Objects.hash(this.feedbackToUser, this.showHelp, this.exit);
84+
return Objects.hash(this.message, this.isError, this.showHelp, this.shouldExit);
85+
}
86+
87+
/**
88+
* Constructs a new command result that only shows a message.
89+
*
90+
* @param message the message to show
91+
*/
92+
public static CommandResult message(String message, Object... args) {
93+
return new CommandResult(String.format(message, args),
94+
/* isError: */ false, /* shouldExit: */ false, /* showHelp: */ false);
95+
}
96+
97+
/**
98+
* Constructs a new command result that shows an error.
99+
*
100+
* @param error the error to show
101+
*/
102+
public static CommandResult error(String error, Object... args) {
103+
return new CommandResult(String.format(error, args),
104+
/* isError: */ true, /* shouldExit: */ false, /* showHelp: */ false);
105+
}
106+
107+
/**
108+
* Constructs a new command result that shows help
109+
*/
110+
public static CommandResult help() {
111+
return new CommandResult("", /* isError: */ false, /* shouldExit: */ false,
112+
/* showHelp: */ true);
113+
}
114+
115+
/**
116+
* Constructs a new command result that quits.
117+
*/
118+
public static CommandResult exit() {
119+
return new CommandResult("", /* isError: */ false, /* shouldExit: */ true,
120+
/* showHelp: */ false);
60121
}
61122
}

0 commit comments

Comments
 (0)