PatchOptions.java
/*
* Copyright (c) 2020, Stein Eldar Johnsen
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package net.morimekta.strings.diff;
import net.morimekta.strings.chr.Color;
import java.util.Optional;
import static java.util.Objects.requireNonNull;
/**
* A class with options for displaying patch strings.
*/
public class PatchOptions {
/** Number of context lines to show before a change. */
public final int before;
/** Number of context lines to show after a change. */
public final int after;
/** String to prepend before the patch header line ({@code @@ ... @@}). */
public final String beforePatch;
/** String to append after the patch header line ({@code @@ ... @@}). */
public final String afterPatch;
/** String to prepend before the comment on a patch header line. */
public final String beforeComment;
/** String to append after the comment on a patch header line. */
public final String afterComment;
/** String to prepend before an equal (unchanged) line. */
public final String beforeEq;
/** String to append after an equal (unchanged) line. */
public final String afterEq;
/** String to prepend before an added line. */
public final String beforeAdd;
/** String to prepend before a deleted line. */
public final String beforeDel;
/** String to append after a changed (added or deleted) line. */
public final String afterChange;
/**
* Create patch options with the given values.
*
* @param before Number of context lines before a change.
* @param after Number of context lines after a change.
* @param beforePatch String to prepend before patch header.
* @param afterPatch String to append after patch header.
* @param beforeComment String to prepend before comment.
* @param afterComment String to append after comment.
* @param beforeEq String to prepend before equal lines.
* @param afterEq String to append after equal lines.
* @param beforeAdd String to prepend before added lines.
* @param beforeDel String to prepend before deleted lines.
* @param afterChange String to append after changed lines.
*/
public PatchOptions(int before,
int after,
String beforePatch,
String afterPatch,
String beforeComment,
String afterComment,
String beforeEq,
String afterEq,
String beforeAdd,
String beforeDel,
String afterChange) {
if (before < 0) throw new IllegalArgumentException("before < 0: " + before);
if (after < 0) throw new IllegalArgumentException("after < 0: " + after);
this.before = before;
this.after = after;
this.beforePatch = requireNonNull(beforePatch, "beforePatch == null");
this.afterPatch = requireNonNull(afterPatch, "afterPatch == null");
this.beforeComment = requireNonNull(beforeComment, "beforeComment == null");
this.afterComment = requireNonNull(afterComment, "afterComment == null");
this.beforeEq = requireNonNull(beforeEq, "beforeEq == null");
this.afterEq = requireNonNull(afterEq, "afterEq == null");
this.beforeAdd = requireNonNull(beforeAdd, "beforeAdd == null");
this.beforeDel = requireNonNull(beforeDel, "beforeDel == null");
this.afterChange = requireNonNull(afterChange, "afterChange == null");
}
/**
* Create a new builder for patch options.
*
* @return A new builder instance.
*/
public static Builder newBuilder() {
return new Builder();
}
/**
* Builder for {@link PatchOptions}.
*/
public static class Builder {
private int before = 0;
private int after = 0;
private String beforePatch = "";
private String afterPatch = "";
private String beforeComment = "";
private String afterComment = "";
private String beforeEq = "";
private String afterEq = "";
private String beforeAdd = "";
private String beforeDel = "";
private String afterChange = "";
/**
* Create a new builder with default (empty/zero) values.
*/
public Builder() {}
/**
* Set all options to their minimal defaults (no context, no decoration).
*
* @return This builder.
*/
public Builder withDefaultMinimal() {
return withBefore(0)
.withAfter(0)
.withBeforePatch("")
.withAfterPatch("")
.withBeforeComment("")
.withAfterComment("")
.withBeforeEq("")
.withAfterEq("")
.withBeforeAdd("")
.withBeforeDel("")
.withAfterChange("");
}
/**
* Set all options to pretty-print defaults with ANSI color codes
* and 3 lines of context.
*
* @return This builder.
*/
public Builder withDefaultPretty() {
return withBefore(3)
.withAfter(3)
.withBeforePatch(new Color(Color.CYAN, Color.DIM).toString())
.withAfterPatch(Color.CLEAR.toString())
.withBeforeComment(Color.DIM.toString())
.withAfterComment(Color.CLEAR.toString())
.withBeforeEq("")
.withAfterEq("")
.withBeforeAdd(Color.GREEN.toString())
.withBeforeDel(Color.RED.toString())
.withAfterChange(Color.CLEAR.toString());
}
/**
* Set number of context lines to show before a change.
*
* @param before Number of lines before.
* @return This builder.
*/
public Builder withBefore(int before) {
if (before < 0) throw new IllegalArgumentException("before < 0: " + before);
this.before = before;
return this;
}
/**
* Set number of context lines to show after a change.
*
* @param after Number of lines after.
* @return This builder.
*/
public Builder withAfter(int after) {
if (after < 0) throw new IllegalArgumentException("after < 0: " + after);
this.after = after;
return this;
}
/**
* Set string to prepend before the patch header line.
*
* @param beforePatch The prefix string, or null for empty.
* @return This builder.
*/
public Builder withBeforePatch(String beforePatch) {
this.beforePatch = Optional.ofNullable(beforePatch).orElse("");
return this;
}
/**
* Set string to append after the patch header line.
*
* @param afterPatch The suffix string, or null for empty.
* @return This builder.
*/
public Builder withAfterPatch(String afterPatch) {
this.afterPatch = Optional.ofNullable(afterPatch).orElse("");
return this;
}
/**
* Set string to prepend before the comment on a patch header line.
*
* @param beforeComment The prefix string, or null for empty.
* @return This builder.
*/
public Builder withBeforeComment(String beforeComment) {
this.beforeComment = Optional.ofNullable(beforeComment).orElse("");
return this;
}
/**
* Set string to append after the comment on a patch header line.
*
* @param afterComment The suffix string, or null for empty.
* @return This builder.
*/
public Builder withAfterComment(String afterComment) {
this.afterComment = Optional.ofNullable(afterComment).orElse("");
return this;
}
/**
* Set string to prepend before an equal (unchanged) line.
*
* @param beforeEq The prefix string, or null for empty.
* @return This builder.
*/
public Builder withBeforeEq(String beforeEq) {
this.beforeEq = Optional.ofNullable(beforeEq).orElse("");
return this;
}
/**
* Set string to append after an equal (unchanged) line.
*
* @param afterEq The suffix string, or null for empty.
* @return This builder.
*/
public Builder withAfterEq(String afterEq) {
this.afterEq = Optional.ofNullable(afterEq).orElse("");
return this;
}
/**
* Set string to prepend before an added line.
*
* @param beforeAdd The prefix string, or null for empty.
* @return This builder.
*/
public Builder withBeforeAdd(String beforeAdd) {
this.beforeAdd = Optional.ofNullable(beforeAdd).orElse("");
return this;
}
/**
* Set string to prepend before a deleted line.
*
* @param beforeDel The prefix string, or null for empty.
* @return This builder.
*/
public Builder withBeforeDel(String beforeDel) {
this.beforeDel = Optional.ofNullable(beforeDel).orElse("");
return this;
}
/**
* Set string to append after a changed (added or deleted) line.
*
* @param afterChange The suffix string, or null for empty.
* @return This builder.
*/
public Builder withAfterChange(String afterChange) {
this.afterChange = Optional.ofNullable(afterChange).orElse("");
return this;
}
/**
* Build the patch options.
*
* @return The new {@link PatchOptions} instance.
*/
public PatchOptions build() {
return new PatchOptions(before,
after,
beforePatch,
afterPatch,
beforeComment,
afterComment,
beforeEq,
afterEq,
beforeAdd,
beforeDel,
afterChange);
}
}
}