changeset 1553:26c51acf00f3

improve stringify
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 06 Oct 2020 19:31:57 -0600
parents 46d4baaad64d
children 83249ce59d13
files src/luan/modules/BasicLuan.java src/luan/modules/lucene/LuceneIndex.java src/luan/modules/lucene/PostgresBackup.java src/luan/modules/parsers/LuanToString.java
diffstat 4 files changed, 137 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/src/luan/modules/BasicLuan.java	Sun Oct 04 20:26:49 2020 -0600
+++ b/src/luan/modules/BasicLuan.java	Tue Oct 06 19:31:57 2020 -0600
@@ -209,27 +209,8 @@
 		}
 	}
 
-	public static String stringify(Object obj,LuanTable options) throws LuanException {
-		LuanToString lts = new LuanToString();
-		if( options != null ) {
-			options = new LuanTable(options);
-			Boolean strict = Utils.removeBoolean(options,"strict");
-			if( strict != null )
-				lts.strict = strict;
-			Boolean numberTypes = Utils.removeBoolean(options,"number_types");
-			if( numberTypes != null )
-				lts.numberTypes = numberTypes;
-			Boolean compressed = Utils.removeBoolean(options,"compressed");
-			if( compressed != null )
-				lts.compressed = compressed;
-			Boolean useLongStrings = Utils.removeBoolean(options,"use_long_strings");
-			if( useLongStrings != null )
-				lts.useLongStrings = useLongStrings;
-			LuanTable longStringKeys = Utils.removeTable(options,"long_string_keys");
-			if( longStringKeys != null )
-				lts.longStringKeys = new HashSet(longStringKeys.asList());
-			Utils.checkEmpty(options);
-		}
+	public static String stringify(Object obj,LuanTable options,LuanTable subOptions) throws LuanException {
+		LuanToString lts = new LuanToString(options,subOptions);
 		return lts.toString(obj);
 	}
 
--- a/src/luan/modules/lucene/LuceneIndex.java	Sun Oct 04 20:26:49 2020 -0600
+++ b/src/luan/modules/lucene/LuceneIndex.java	Tue Oct 06 19:31:57 2020 -0600
@@ -860,9 +860,9 @@
 			final int nPostgres = idsPostgres.size();
 			int iLucene = 0;
 			int iPostgres = 0;
-			LuanToString lts = new LuanToString();
-			lts.strict = true;
-			lts.numberTypes = true;
+			LuanToString lts = new LuanToString(null,null);
+			lts.settingsInit.strict = true;
+			lts.settingsInit.numberTypes = true;
 			while( iLucene < nLucene && iPostgres < nPostgres ) {
 				long idLucene = idsLucene.get(iLucene);
 				long idPostgres = idsPostgres.get(iPostgres);
--- a/src/luan/modules/lucene/PostgresBackup.java	Sun Oct 04 20:26:49 2020 -0600
+++ b/src/luan/modules/lucene/PostgresBackup.java	Tue Oct 06 19:31:57 2020 -0600
@@ -34,7 +34,7 @@
 	private final PreparedStatement updateStmt;
 	private final PreparedStatement deleteStmt;
 	private int trans = 0;
-	private final LuanToString luanToString = new LuanToString();
+	private final LuanToString luanToString = new LuanToString(null,null);
 
 	PostgresBackup(Luan luan,LuanTable spec)
 		throws ClassNotFoundException, SQLException, LuanException
@@ -82,8 +82,8 @@
 			"delete from lucene where id=?"
 		);
 
-		luanToString.strict = true;
-		luanToString.numberTypes = true;
+		luanToString.settingsInit.strict = true;
+		luanToString.settingsInit.numberTypes = true;
 	}
 
 	Connection newConnection() throws SQLException {
--- a/src/luan/modules/parsers/LuanToString.java	Sun Oct 04 20:26:49 2020 -0600
+++ b/src/luan/modules/parsers/LuanToString.java	Tue Oct 06 19:31:57 2020 -0600
@@ -3,6 +3,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.HashSet;
 import java.util.Collections;
 import luan.Luan;
 import luan.LuanTable;
@@ -11,19 +12,85 @@
 
 
 public final class LuanToString {
-	public boolean strict = false;
-	public boolean numberTypes = false;
-	public boolean compressed = false;
-	public boolean useLongStrings = false;
-	public Set longStringKeys = Collections.emptySet();
+	public static class Settings implements Cloneable {
+		public boolean strict = false;
+		public boolean numberTypes = false;
+		public boolean compressed = false;
+		public boolean longStrings = false;
+		public boolean inline = false;
+
+		void applyOptions(LuanTable options) throws LuanException {
+			Boolean b;
+			b = (Boolean)options.get("strict");
+			if( b != null )
+				strict = b;
+			b = (Boolean)options.get("number_types");
+			if( b != null )
+				numberTypes = b;
+			b = (Boolean)options.get("compressed");
+			if( b != null )
+				compressed = b;
+			b = (Boolean)options.get("long_strings");
+			if( b != null )
+				longStrings = b;
+			b = (Boolean)options.get("inline");
+			if( b != null )
+				inline = b;
+		}
+
+		public Settings cloneSettings() {
+			try {
+				return (Settings)clone();
+			} catch(CloneNotSupportedException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+	private static final Settings keySettings = new Settings();
+	private static final Set<String> settingsKeys = new HashSet<String>();
+	static {
+		Collections.addAll(settingsKeys,"strict","number_types","compressed","long_strings","inline");
+	}
+
+	private static void checkOptions(LuanTable options) throws LuanException {
+		for( Map.Entry entry : options.iterable() ) {
+			if( !settingsKeys.contains(entry.getKey()) )
+				throw new LuanException("invalid option: "+entry.getKey());
+			if( !(entry.getValue() instanceof Boolean) )
+				throw new LuanException("options values must be boolean");
+		}
+	}
+
+	public final Settings settingsInit = new Settings();
+	private final LuanTable subOptions;
+
+	public LuanToString(LuanTable options,LuanTable subOptions) throws LuanException {
+		this.subOptions = subOptions;
+		if( options != null ) {
+			checkOptions(options);
+			settingsInit.applyOptions(options);
+		}
+		if( subOptions != null ) {
+			for( Map.Entry entry : subOptions.iterable() ) {
+/*
+				if( !(entry.getKey() instanceof String) )
+					throw new LuanException("sub_options keys must be strings");
+*/
+				if( !(entry.getValue() instanceof LuanTable) )
+					throw new LuanException("sub_options keys must be tables");
+				LuanTable tbl = (LuanTable)entry.getValue();
+				checkOptions(tbl);
+			}
+		}
+	}
 
 	public String toString(Object obj) throws LuanException {
 		StringBuilder sb = new StringBuilder();
-		toString(obj,sb,0,useLongStrings);
+		toString(obj,sb,0,settingsInit);
 		return sb.toString();
 	}
 
-	private void toString(Object obj,StringBuilder sb,int indented,boolean longStrings) throws LuanException {
+	private void toString(Object obj,StringBuilder sb,int indented,Settings settings) throws LuanException {
 		if( obj == null ) {
 			sb.append( "nil" );
 			return;
@@ -33,65 +100,92 @@
 			return;
 		}
 		if( obj instanceof Number ) {
-			toString((Number)obj,sb);
+			toString((Number)obj,sb,settings);
 			return;
 		}
 		if( obj instanceof String ) {
-			toString((String)obj,sb,longStrings);
+			toString((String)obj,sb,settings);
 			return;
 		}
 		if( obj instanceof LuanTable ) {
-			toString((LuanTable)obj,sb,indented,longStrings);
+			toString((LuanTable)obj,sb,indented,settings);
 			return;
 		}
-		if( strict )
+		if( settings.strict )
 			throw new LuanException("can't handle type "+Luan.type(obj));
 		sb.append( '<' );
 		sb.append( obj );
 		sb.append( '>' );
 	}
 
-	private void toString(LuanTable tbl,StringBuilder sb,int indented,boolean longStrings) throws LuanException {
+	private void toString(LuanTable tbl,StringBuilder sb,int indented,Settings settings) throws LuanException {
 		List list = tbl.asList();
 		Map map = tbl.rawMap();
 		sb.append( '{' );
 		boolean first = true;
 		for( Object obj : list ) {
-			if( !compressed )
+			if( settings.compressed ) {
+				if( first )
+					first = false;
+				else
+					sb.append( ',' );
+			} else if( settings.inline ) {
+				if( first ) {
+					first = false;
+					sb.append( ' ' );
+				} else
+					sb.append( ", " );
+			} else {
 				indent(sb,indented+1);
-			else if( first )
-				first = false;
-			else
-				sb.append( ',' );
-			toString(obj,sb,indented+1,longStrings);
+			}
+			toString(obj,sb,indented+1,settings);
 		}
 		for( Object obj : map.entrySet() ) {
 			Map.Entry entry = (Map.Entry)obj;
-			if( !compressed )
+			if( settings.compressed ) {
+				if( first )
+					first = false;
+				else
+					sb.append( ',' );
+			} else if( settings.inline ) {
+				if( first ) {
+					first = false;
+					sb.append( ' ' );
+				} else
+					sb.append( ", " );
+			} else {
 				indent(sb,indented+1);
-			else if( first )
-				first = false;
-			else
-				sb.append( ',' );
-			toString(entry,sb,indented+1);
+			}
+			toString(entry,sb,indented+1,settings);
 		}
-		if( !compressed && (!list.isEmpty() || !map.isEmpty()) )
-			indent(sb,indented);
+		if( !list.isEmpty() || !map.isEmpty() ) {
+			if( settings.compressed ) {
+			} else if( settings.inline ) {
+				sb.append( ' ' );
+			} else {
+				indent(sb,indented);
+			}
+		}
 		sb.append( '}' );
 		return;
 	}
 
-	private void toString(Map.Entry entry,StringBuilder sb,int indented) throws LuanException {
+	private void toString(Map.Entry entry,StringBuilder sb,int indented,Settings settings) throws LuanException {
 		Object key = entry.getKey();
 		if( key instanceof String && ((String)key).matches("[a-zA-Z_][a-zA-Z_0-9]*") ) {
 			sb.append( (String)key );
 		} else {
 			sb.append( '[' );
-			toString( key, sb, indented, false );
+			toString( key, sb, indented, keySettings );
 			sb.append( ']' );
 		}
-		sb.append( compressed ? "=" : " = " );
-		toString( entry.getValue(), sb, indented, longStringKeys.contains(key) );
+		sb.append( settings.compressed ? "=" : " = " );
+		LuanTable options = (LuanTable)subOptions.get(key);
+		if( options != null ) {
+			settings = settings.cloneSettings();
+			settings.applyOptions(options);
+		}
+		toString( entry.getValue(), sb, indented, settings );
 	}
 
 	private void indent(StringBuilder sb,int indented) {
@@ -101,13 +195,13 @@
 		}
 	}
 
-	private void toString(Number n,StringBuilder sb) throws LuanException {
-		if( numberTypes ) {
+	private void toString(Number n,StringBuilder sb,Settings settings) throws LuanException {
+		if( settings.numberTypes ) {
 			sb.append( n.getClass().getSimpleName().toLowerCase() );
 			sb.append( '(' );
 		}
 		sb.append( Luan.toString(n) );
-		if( numberTypes )
+		if( settings.numberTypes )
 			sb.append( ')' );
 	}
 
@@ -123,8 +217,8 @@
 		}
 	}
 
-	private void toString(String s,StringBuilder sb,boolean longStrings) {
-		if( longStrings ) {
+	private void toString(String s,StringBuilder sb,Settings settings) {
+		if( settings.longStrings ) {
 			StringBuilder start = new StringBuilder("[[");
 			if( s.indexOf('\n') != -1 )
 				start.append('\n');