All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dakusui.crest.core.Eater Maven / Gradle / Ivy

package com.github.dakusui.crest.core;

import com.github.dakusui.crest.utils.printable.Printable;
import junit.framework.AssertionFailedError;

import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.github.dakusui.crest.utils.printable.Predicates.equalTo;
import static java.util.Objects.requireNonNull;

public interface Eater {
  Eater after(T target);

  /**
   * Builds a function.
   *
   * @return The function.
   */
  Function build();

  /**
   * A synonym of {@code build} method.
   *
   * @return A built function.
   */
  default Function $() {
    return build();
  }

  abstract class Base implements Eater {
    final T           finder;
    final Eater parent;

    Base(Eater parent, T finder) {
      this.parent = parent;
      this.finder = requireNonNull(finder);
    }

    @SuppressWarnings("unchecked")
    @Override
    public Function build() {
      return this.parent == null
          ? toFunction()
          : this.parent.build().andThen(toFunction());
    }

    Function toFunction() {
      return ChainedFunction.create(
          Printable.function(
              describeFunction(),
              createFunction()
          ));
    }

    String describeFunction() {
      return String.format("->after[%s]", this.finder);
    }

    protected abstract Function createFunction();

  }

  class RegexEater extends Base {
    public RegexEater(Eater parent, String target) {
      super(parent, target);
    }

    /**
     * @param target A regex
     * @return A new {@code RegexEater}
     */
    @Override
    public RegexEater after(String target) {
      return new RegexEater(this, target);
    }

    protected Function createFunction() {
      return (String container) -> {
        Matcher matcher = Pattern.compile(String.format("(%s)", finder)).matcher(container);
        if (matcher.find())
          return restOf(container, matcher.group(1));
        throw new AssertionFailedError(String.format("regex:%s was not found", finder));
      };
    }

    private String restOf(String container, String matched) {
      return container.substring(matched.length() + container.indexOf(matched));
    }
  }

  class ListEater extends Base, List> {

    public ListEater(Eater, List> parent, Predicate target) {
      super(parent, target);
    }

    @Override
    protected Function, List> createFunction() {
      return container -> {
        int index = findTarget(container);
        if (index < 0)
          throw new AssertionFailedError(String.format("Element:%s was not found", finder));
        return container.subList(index + 1, container.size());
      };
    }

    @Override
    public ListEater after(Predicate finder) {
      return new ListEater<>(this, finder);
    }

    public ListEater afterElement(T target) {
      return new ListEater<>(this, equalTo(target));
    }

    int findTarget(List container) {
      int i = 0;
      for (T elem : container) {
        if (this.finder.test(elem))
          return i;
        i++;
      }
      return -1;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy