LuaSource.java
/*
* @copyright defined in LICENSE.txt
*/
package ship.test;
import static hera.util.ValidationUtils.assertTrue;
import static java.lang.String.format;
import static java.util.Collections.EMPTY_LIST;
import static org.slf4j.LoggerFactory.getLogger;
import static ship.util.AnsiMessagePrinter.COLOR_GREEN;
import static ship.util.AnsiMessagePrinter.COLOR_RESET;
import hera.util.IntRange;
import java.util.List;
import java.util.StringJoiner;
import java.util.stream.IntStream;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.slf4j.Logger;
public class LuaSource {
protected final transient Logger logger = getLogger(getClass());
protected static String[] splitToLines(final String script) {
return script.split("\\r?\\n");
}
@RequiredArgsConstructor
@ToString
class SourceLine {
@Getter
protected final int linenumber;
@Getter
protected final String text;
}
@Getter
protected final String script;
@Getter
protected final SourceLine[] lines;
/**
* Constructor with raw script content.
*
* @param script raw text
*/
public LuaSource(final String script) {
this.script = script;
final String[] lines = splitToLines(script);
this.lines = new SourceLine[lines.length];
for (int i = 0, n = lines.length; i < n; ++i) {
this.lines[i] = new SourceLine(i + 1, lines[i]);
logger.trace("Line: {}", this.lines[i]);
}
}
/**
* Create source with left-side linenumber.
*
* @return formatted string
*/
@Override
public String toString() {
return toString(0, lines.length, EMPTY_LIST);
}
/**
* Create source with left-side linenumber.
*
* @param from start line number
* @param to end line number
* @param highlights need to highlight lines
*
* @return formatted string
*/
public String toString(final int from, final int to, final List<Integer> highlights) {
logger.debug("{} ~ {}", from, to);
final int digit = (int) (Math.log10(lines.length) + 1);
assertTrue(from < to);
final IntRange range = new IntRange(0, lines.length).select(new IntRange(from, to));
logger.trace("{}", range);
final StringJoiner joiner = new StringJoiner("\n");
IntStream.range(range.v1, range.v2)
.mapToObj(lineNumber -> {
final SourceLine line = lines[lineNumber];
final int n = line.getLinenumber();
if (highlights.contains(line.getLinenumber())) {
return format("%" + digit + "s |%s%s%s", n, COLOR_GREEN, line.getText(), COLOR_RESET);
} else {
return format("%" + digit + "s |%s", n, line.getText());
}
})
.forEach(joiner::add);
return joiner.toString();
}
}