Skip to content

Commit

Permalink
Improve transaction conversion to JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Aug 18, 2023
1 parent 39e66c5 commit f009c5c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 13 deletions.
46 changes: 33 additions & 13 deletions convex-core/src/main/java/convex/core/lang/RT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1654,8 +1654,8 @@ public static <T> T jvm(ACell o) {
* - Characters become a String
* - Blobs become a hex string representation '0x....'
*
* @param o Value to convert to JVM type
* @return Java value which represents JSON object
* @param o Value to convert to JSON value object
* @return Java Object which represents JSON value
*/
@SuppressWarnings("unchecked")
public static <T> T json(ACell o) {
Expand All @@ -1672,16 +1672,7 @@ public static <T> T json(ACell o) {
return (T) (Long)((Address) o).toExactLong();
if (o instanceof AMap) {
AMap<?,?> m= (AMap<?,?>)o;
long n=m.count();
HashMap<String,Object> hm=new HashMap<>();
for (long i=0; i<n; i++) {
MapEntry<?,?> me=m.entryAt(i);
ACell k=me.getKey();
String sk=(k instanceof AString)?k.toString():RT.toString(k);
Object v=json(me.getValue());
hm.put(sk, v);
}
return (T) hm;
return (T)jsonMap(m);
}
if (o instanceof ASequence) {
ASequence<?> seq= (ASequence<?>)o;
Expand All @@ -1695,9 +1686,38 @@ public static <T> T json(ACell o) {
return (T) list;
}


return (T) o.toString();
}

/**
* Converts a CVM Map to a JSON representation
* @param m Map to convert to JSON representation
* @return Java value which represents JSON object
*/
public static HashMap<String,Object> jsonMap(AMap<?,?> m) {
int n=m.size();
HashMap<String,Object> hm=new HashMap<String,Object>(n);
for (long i=0; i<n; i++) {
MapEntry<?,?> me=m.entryAt(i);
ACell k=me.getKey();
String sk=jsonKey(k);
Object v=json(me.getValue());
hm.put(sk, v);
}
return hm;
}

/**
* Gets a String from a value suitable for use as a JSON map key
* @param k Value to convert to a JSON key
* @return String usable as JSON key
*/
public static String jsonKey(ACell k) {
if (k instanceof AString) return k.toString();
if (k instanceof Keyword) return ((Keyword)k).getName().toString();
return RT.toString(k);
}


/**
* Get the runtime Type of any CVM value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package convex.core.transactions;

import java.util.HashMap;

import convex.core.lang.RT;

public class Transactions {

public static HashMap<String,Object> toJSON(ATransaction tx) {
HashMap<String,Object> result= RT.jsonMap(tx);
result.put("type", tx.getClass().getSimpleName());
return result;
}
}
11 changes: 11 additions & 0 deletions convex-core/src/test/java/convex/core/TransactionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.util.HashMap;

import org.junit.jupiter.api.Test;

import convex.core.data.AVector;
Expand All @@ -18,7 +20,9 @@
import convex.core.lang.Symbols;
import convex.core.transactions.ATransaction;
import convex.core.transactions.Call;
import convex.core.transactions.Invoke;
import convex.core.transactions.Multi;
import convex.core.transactions.Transactions;
import convex.core.transactions.Transfer;
import static convex.test.Assertions.*;

Expand Down Expand Up @@ -56,6 +60,13 @@ public void testTransfer() {
doTransactionTests(t1);
}

@Test public void testJSON() {
Invoke tx=Invoke.create(VILLAIN, 1, "(+ 2 3)");
HashMap<String,Object> hm=Transactions.toJSON(tx);
assertEquals("Invoke",hm.get("type"));
assertEquals(1L,hm.get("sequence"));
}

@Test
public void testMulti() {
Transfer t1=Transfer.create(HERO, 120, VILLAIN, 1000);
Expand Down
4 changes: 4 additions & 0 deletions convex-core/src/test/java/convex/core/lang/RTTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public void testJSON() {
assertEquals("foo",RT.json(Symbols.FOO));
assertEquals(":foo",RT.json(Keywords.FOO));

// Note keywords get colon removed when used as JSON key
assertEquals(":bar",RT.jsonMap(Maps.of(Keywords.FOO, Keywords.BAR)).get("foo"));


// JSON should convert keys to strings
assertEquals(Maps.of("1",2), RT.cvm(RT.json(Maps.of(1,2))));
assertEquals(Maps.of("[]",3), RT.cvm(RT.json(Maps.of(Vectors.empty(),3))));
Expand Down

0 comments on commit f009c5c

Please sign in to comment.