@Nonnull
	private static StringDiff.Diff deserializeStringDiff(@Nonnull JsonReader jr) throws IOException {
		StringDiff.DiffType type = null;
		int startA = -1;
		int startB = -1;
		int endA = -1;
		int endB = -1;
		String textA = null;
		String textB = null;

		jr.beginObject();
		while (jr.hasNext()) {
			String key = jr.nextName();
			switch (key) {
				case KEY_TYPE -> type = StringDiff.DiffType.valueOf(jr.nextString());
				case KEY_TEXT_A -> textA = jr.nextString();
				case KEY_TEXT_B -> textB = jr.nextString();
				case KEY_START_A -> startA = jr.nextInt();
				case KEY_START_B -> startB = jr.nextInt();
				case KEY_END_A -> endA = jr.nextInt();
				case KEY_END_B -> endB = jr.nextInt();
			}
		}
		jr.endObject();

		if (type == null)
			throw new IOException("String diff missing key: " + KEY_TYPE);
		if (textA == null)
			throw new IOException("String diff missing key: " + KEY_TEXT_A);
		if (textB == null)
			throw new IOException("String diff missing key: " + KEY_TEXT_B);
		if (startA == -1)
			throw new IOException("String diff missing key: " + KEY_START_A);
		if (startB == -1)
			throw new IOException("String diff missing key: " + KEY_START_B);
		if (endA == -1)
			throw new IOException("String diff missing key: " + KEY_END_A);
		if (endB == -1)
			throw new IOException("String diff missing key: " + KEY_END_B);

		return new StringDiff.Diff(type, startA, startB, endA, endB, textA, textB);
	}
Maps a JSON file into a workspace patch.

@param workspace
		Workspace to apply the patch to.
@param patchContents
		JSON outlining patch contents.

@return A workspace patch instance.

@throws PatchGenerationException
		When the JSON file couldn't be parsed, or its contents could not be found in the workspace.
recaf-core/src/main/java/software/coley/recaf/services/workspace/patch/PatchSerialization.java