Pārlūkot izejas kodu

Adding StringFormatter for easier formatting of strings without needing to worry about fmt specifiers.

Sam Jaffe 8 gadi atpakaļ
vecāks
revīzija
250156afea

+ 7 - 1
src/org/leumasjaffe/charsheet/util/StringHelper.java

@@ -1,5 +1,7 @@
 package org.leumasjaffe.charsheet.util;
 
+import org.leumasjaffe.format.StringFormatter;
+
 import lombok.experimental.UtilityClass;
 
 @UtilityClass
@@ -32,8 +34,12 @@ public class StringHelper {
 		else { return toString(i); }
 	}
 	
-	public static String toSignedString(int i, int ignore) {
+	public String toSignedString(int i, int ignore) {
 		if ( i == ignore ) { return ""; }
 		else { return toSignedString(i); }
 	}
+	
+	public String format(String logFmtString, Object... args) {
+		return new StringFormatter(logFmtString).format(args);
+	}
 }

+ 18 - 0
src/org/leumasjaffe/format/CustomToString.java

@@ -0,0 +1,18 @@
+package org.leumasjaffe.format;
+
+import java.util.function.Function;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.experimental.FieldDefaults;
+
+@AllArgsConstructor
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class CustomToString<T> {
+	T object;
+	Function<T, String> toStringFunction;
+	
+	public String toString() {
+		return toStringFunction.apply(object);
+	}
+}

+ 27 - 0
src/org/leumasjaffe/format/Named.java

@@ -0,0 +1,27 @@
+package org.leumasjaffe.format;
+
+import java.util.Objects;
+
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.experimental.FieldDefaults;
+
+@Data
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class Named {
+	String name;
+	Object value;
+	
+	public Named(String n, Object v) {
+		Objects.requireNonNull(n);
+		this.name = n;
+		this.value = v;
+		if (n.matches("\\{|\\}|%")) {
+			throw new IllegalArgumentException("Cannot use '{', '}', or '%' in named arguments!");
+		}
+	}
+	
+	public String toString() {
+		return String.valueOf(value);
+	}
+}

+ 61 - 0
src/org/leumasjaffe/format/StringFormatter.java

@@ -0,0 +1,61 @@
+package org.leumasjaffe.format;
+
+import java.util.HashMap;
+import java.util.Objects;
+
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class StringFormatter {
+	private static final class NameMap extends HashMap<String, Object> {
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = -2243574068000774442L;
+
+		NameMap(Object... args) {
+			for (Object arg : args) {
+				Objects.requireNonNull(arg);
+				if (arg instanceof Named) {
+					put(((Named) arg).getName(), arg);
+				}
+			}
+		}
+	}
+	
+	String fmt;
+	
+	public StringFormatter(String logFmtString) {
+		this.fmt = logFmtString;
+	}
+	
+	public String format(Object... args) {
+		final StringBuilder str = new StringBuilder(fmt.length());
+		
+		int currentIdx = 0;
+		final NameMap named = new NameMap(args);
+		
+		int lpos = 0;
+		for (int pos = fmt.indexOf('{'); pos != -1; lpos = pos+1, pos = fmt.indexOf('{', lpos)) {
+			str.append(fmt.substring(lpos, pos));
+			int epos = fmt.indexOf('}', pos);
+
+			if (fmt.charAt(pos+1) == '{') { 
+				str.append(fmt.substring(++pos, ++epos));
+			} else if (epos == pos+1) {
+				str.append(args[currentIdx++]);
+			} else {
+				final String token = fmt.substring(pos+1, epos);
+				if (Character.isDigit(token.charAt(0))) {
+					str.append(args[Integer.parseInt(token)]);
+				} else { // In theory, I could add a format-mode here too
+					str.append(named.get(token));
+				}
+			}
+			pos = epos;
+		}
+		str.append(fmt.substring(lpos));
+		return str.toString();
+	}
+}