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 {
    public final int    before;
    public final int    after;
    // {beforePath}@@ ... @@{afterPatch}{beforeComment} -- ...{afterComment}
    public final String beforePatch;
    public final String afterPatch;
    public final String beforeComment;
    public final String afterComment;
    // {beforeEq} ...{afterEq}
    public final String beforeEq;
    public final String afterEq;
    // {beforeAdd}+...{afterChange}
    public final String beforeAdd;
    // {beforeDel}-...{afterChange}
    public final String beforeDel;
    public final String afterChange;

    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");
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static class Builder {
        private int    before        = 0;
        private int    after         = 0;
        // {beforePath}@@ ... @@{afterPatch}{beforeComment} -- ...{afterComment}
        private String beforePatch   = "";
        private String afterPatch    = "";
        private String beforeComment = "";
        private String afterComment  = "";
        // {beforeEq} ...{afterEq}
        private String beforeEq      = "";
        private String afterEq       = "";
        // {beforeAdd}+...{afterChange}
        private String beforeAdd     = "";
        // {beforeDel}-...{afterChange}
        private String beforeDel     = "";
        private String afterChange   = "";

        public Builder() {}

        public Builder withDefaultMinimal() {
            return withBefore(0)
                    .withAfter(0)
                    .withBeforePatch("")
                    .withAfterPatch("")
                    .withBeforeComment("")
                    .withAfterComment("")
                    .withBeforeEq("")
                    .withAfterEq("")
                    .withBeforeAdd("")
                    .withBeforeDel("")
                    .withAfterChange("");
        }

        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());
        }

        public Builder withBefore(int before) {
            if (before < 0) throw new IllegalArgumentException("before < 0: " + before);
            this.before = before;
            return this;
        }

        public Builder withAfter(int after) {
            if (after < 0) throw new IllegalArgumentException("after < 0: " + after);
            this.after = after;
            return this;
        }

        public Builder withBeforePatch(String beforePatch) {
            this.beforePatch = Optional.ofNullable(beforePatch).orElse("");
            return this;
        }

        public Builder withAfterPatch(String afterPatch) {
            this.afterPatch = Optional.ofNullable(afterPatch).orElse("");
            return this;
        }

        public Builder withBeforeComment(String beforeComment) {
            this.beforeComment = Optional.ofNullable(beforeComment).orElse("");
            return this;
        }

        public Builder withAfterComment(String afterComment) {
            this.afterComment = Optional.ofNullable(afterComment).orElse("");
            return this;
        }

        public Builder withBeforeEq(String beforeEq) {
            this.beforeEq = Optional.ofNullable(beforeEq).orElse("");
            return this;
        }

        public Builder withAfterEq(String afterEq) {
            this.afterEq = Optional.ofNullable(afterEq).orElse("");
            return this;
        }

        public Builder withBeforeAdd(String beforeAdd) {
            this.beforeAdd = Optional.ofNullable(beforeAdd).orElse("");
            return this;
        }

        public Builder withBeforeDel(String beforeDel) {
            this.beforeDel = Optional.ofNullable(beforeDel).orElse("");
            return this;
        }

        public Builder withAfterChange(String afterChange) {
            this.afterChange = Optional.ofNullable(afterChange).orElse("");
            return this;
        }

        public PatchOptions build() {
            return new PatchOptions(before,
                                    after,
                                    beforePatch,
                                    afterPatch,
                                    beforeComment,
                                    afterComment,
                                    beforeEq,
                                    afterEq,
                                    beforeAdd,
                                    beforeDel,
                                    afterChange);
        }
    }
}