package org.andork.unit;
import java.text.CharacterIterator;
import java.util.function.Function;
import org.andork.func.CharPredicate;
public class UnitParser<T extends UnitType<T>> implements Function<CharacterIterator, Unit<T>> {
T unitType;
CharPredicate isUnitStartChar;
CharPredicate isUnitChar;
Function<String, Unit<T>> unitLookup;
public UnitParser(T unitType, CharPredicate isUnitStartChar, CharPredicate isUnitChar,
Function<String, Unit<T>> unitLookup) {
super();
this.unitType = unitType;
this.isUnitStartChar = isUnitStartChar;
this.isUnitChar = isUnitChar;
this.unitLookup = unitLookup;
}
@Override
public Unit<T> apply(CharacterIterator t) {
char c = t.current();
while (Character.isWhitespace(c)) {
c = t.next();
}
if (!isUnitStartChar.test(c)) {
return null;
}
StringBuilder sb = new StringBuilder();
while (isUnitStartChar.test(c)) {
if (sb.length() > 0) {
sb.append(' ');
}
while (isUnitChar.test(c)) {
sb.append(c);
c = t.next();
}
while (Character.isWhitespace(c)) {
c = t.next();
}
}
Unit<T> result = unitLookup.apply(sb.toString());
if (result == null) {
throw new IllegalArgumentException("Unrecognized unit: " + sb.toString());
}
return result;
}
}