Skip to content

Commit

Permalink
Change encode API and update near-runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
willemneal committed Sep 13, 2019
1 parent 3edc33a commit a8c363c
Show file tree
Hide file tree
Showing 14 changed files with 1,024 additions and 690 deletions.
117 changes: 56 additions & 61 deletions bindings/assembly/nearEntry.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@

import { storage, near, base64, base58 } from 'near-runtime-ts';
import { storage, near, base64, base58 } from "near-runtime-ts";
//@ts-ignore
import { Buffer } from "assemblyscript-json/util";
import { JSONEncoder, JSONDecoder, ThrowingJSONHandler, DecoderState } from "assemblyscript-json";
import { u128 } from "bignum";
// Runtime functions
// tslint:disable: no-unsafe-any



type Usize = u64;
//@ts-ignore
@global
Expand All @@ -32,19 +29,15 @@ declare function value_return(value_len: Usize, value_ptr: Usize): void;
@external("env", "panic")
declare function panic(): void;



/// <reference types="../node_modules/assemblyscript/std/assembly/rt/index.d.ts" />

abstract class Value {
static String(str: string): Value {
return new Str(str)
return new Str(str);
}
static Number(num: i64): Value {
return new Num(num)
return new Num(num);
}
static Bool(b: bool): Value {
return new Bools(b)
return new Bools(b);
}
static Null(): Value {
return new Null();
Expand All @@ -57,22 +50,22 @@ abstract class Value {
}

toString(): string {
if (this instanceof Str){
if (this instanceof Str) {
return (<Str>this).toString();
}
if (this instanceof Num){
if (this instanceof Num) {
return (<Num>this).toString();
}
if (this instanceof Bools){
if (this instanceof Bools) {
return (<Bools>this).toString();
}
if (this instanceof Null){
if (this instanceof Null) {
return (<Null>this).toString();
}
if (this instanceof Arr){
if (this instanceof Arr) {
return (<Arr>this).toString();
}
if (this instanceof Obj){
if (this instanceof Obj) {
return (<Obj>this).toString();
}
return "Value";
Expand Down Expand Up @@ -128,7 +121,7 @@ class Arr extends Value {
}

push(obj: Value): void {
this._arr.push(obj)
this._arr.push(obj);
}

toString(): string {
Expand Down Expand Up @@ -158,15 +151,15 @@ class Obj extends Value {
if (!this._obj.has(key)) {
return null;
}
return this._obj.get(key)
return this._obj.get(key);
}

toString(): string {
let objs: string[] = [];
for (let i: i32 = 0; i < this.keys.length; i++){
objs.push("\"" +this.keys[i]+"\":"+ this._obj.get(this.keys[i]).toString());
const objs: string[] = [];
for (let i: i32 = 0; i < this.keys.length; i++) {
objs.push("\"" + this.keys[i] + "\":" + this._obj.get(this.keys[i]).toString());
}
return "{"+ objs.join(",") + "}";
return "{" + objs.join(",") + "}";
}

has(key: string): bool {
Expand All @@ -182,7 +175,7 @@ class Handler extends ThrowingJSONHandler {
}

reset(): void {
while (this.stack.length > 0){
while (this.stack.length > 0) {
this.stack.pop();
}
}
Expand All @@ -192,27 +185,27 @@ class Handler extends ThrowingJSONHandler {
}

setString(name: string, value: string): void {
let obj: Value = Value.String(value);
const obj: Value = Value.String(value);
this.addValue(name, obj);
}

setBoolean(name: string, value: bool): void {
let obj = Value.Bool(value);
const obj = Value.Bool(value);
this.addValue(name, obj);
}

setNull(name: string): void {
let obj = Value.Null();
const obj = Value.Null();
this.addValue(name, obj);
}

setInteger(name: string, value: i64): void {
let obj = Value.Number(value);
const obj = Value.Number(value);
this.addValue(name, obj);
}

pushArray(name: string): bool {
let obj: Value = Value.Array();
const obj: Value = Value.Array();
this.addValue(name, obj);
this.stack.push(obj);
return true;
Expand All @@ -225,9 +218,9 @@ class Handler extends ThrowingJSONHandler {
}

pushObject(name: string): bool {
let obj: Value = Value.Object();
const obj: Value = Value.Object();
this.addValue(name, obj);
this.stack.push(obj)
this.stack.push(obj);
return true;
}

Expand All @@ -243,35 +236,29 @@ class Handler extends ThrowingJSONHandler {
return;
}
if (this.peek instanceof Obj) {
(this.peek as Obj).set(name, obj)
(this.peek as Obj).set(name, obj);
}
else if (this.peek instanceof Arr) {
(<Arr>this.peek).push(obj);
}
}
}


@global()
class JSON {
private static handler: Handler = new Handler();
private static decoder: JSONDecoder<Handler> = new JSONDecoder<Handler>(JSON.handler);
static parse(str: Uint8Array ): Obj {
JSON.decoder.deserialize(str);
let res = JSON.decoder.handler.peek as Obj;
const res = JSON.decoder.handler.peek as Obj;
JSON.decoder.handler.reset();
return res;
}
}






//@ts-ignore
@global
function encode<T>(encoder: JSONEncoder, value: T, name: string | null = ""): JSONEncoder {
function encode<T, Output = Uint8Array>(value: T, name: string | null = "", encoder: JSONEncoder = new JSONEncoder()): Output {
if (isBoolean<T>()) {
//@ts-ignore
encoder.setBoolean(name, value);
Expand All @@ -298,54 +285,62 @@ function encode<T>(encoder: JSONEncoder, value: T, name: string | null = ""): JS
encoder.pushArray(name);
for (let i: i32 = 0; i < value.length; i++) {
//@ts-ignore
encode(encoder, value[i], null);
encode<valueof<T>, JSONEncoder>(value[i], null, encoder);
}
encoder.popArray();
}
} else { // Is an object
if (value instanceof u128){
if (value instanceof u128) {
encoder.setString(name, value.toString());
} else {
//@ts-ignore
value.encode(encoder, name);
value._encode(name, encoder);
}
}
} else {
throw new Error("Encoding failed");
}
return encoder;
var output: Output;
//@ts-ignore
if (output instanceof Uint8Array) {
//@ts-ignore
return <Output>encoder.serialize();
}
//@ts-ignore
assert( output instanceof JSONEncoder, "Bad return type for encoder");
//@ts-ignore
return <Output>encoder;
}

//@ts-ignore
@inline
function getStr(val: Value, name: String): string {
assert(val instanceof Str, "Value with Key: "+ name +" is not a string or null");
assert(val instanceof Str, "Value with Key: " + name + " is not a string or null");
return (<Str>val)._str;
}

function decodeArray<T>(val: Value, name: string): Array<T> {
assert(val instanceof Arr, "Value with Key: " + name + " is not an array or null.");
let res = new Array<T>();
let arr = (<Arr>val)._arr;
for (let i: i32 = 0; i < arr.length; i++){
const res = new Array<T>();
const arr = (<Arr>val)._arr;
for (let i: i32 = 0; i < arr.length; i++) {
let item: T = decode<T, Value>(arr[i]);
res.push(item);
}
return res;
}


//@ts-ignore
@global
function decode<T, V = Uint8Array>(buf: V, name: string = ""): T {
let buffer = <Value>(buf instanceof Uint8Array ? JSON.parse(buf) : buf);
let val: Value;
if (buffer instanceof Obj && name != ""){
const buffer = <Value>(buf instanceof Uint8Array ? JSON.parse(buf) : buf);
var val: Value;
if (buffer instanceof Obj && name != "") {
const obj: Obj = <Obj>buffer;
let res = obj.get(name);
if (res == null){
if (res == null) {
//@ts-ignore
return <T>null
return <T>null;
}
val = res;
}else {
Expand All @@ -361,20 +356,20 @@ function decode<T, V = Uint8Array>(buf: V, name: string = ""): T {
return getStr(val, name);
}
if (isBoolean<T>()) {
assert(val instanceof Bools, "Value with Key: "+ name + " with type " + nameof<T>() +" is not a string");
assert(val instanceof Bools, "Value with Key: " + name + " with type " + nameof<T>() + " is not a string");
//@ts-ignore
return (<Bools>val)._bool
return (<Bools>val)._bool;
}
var value: T;
if (isInteger<T>()) {
//@ts-ignore
if (value instanceof u64 || value instanceof i64) {
assert(val instanceof Str, "Value with Key: "+ name + " with type " + nameof<T>() +" is an 64-bit integer and is expected to be encoded as a string");
assert(val instanceof Str, "Value with Key: " + name + " with type " + nameof<T>() + " is an 64-bit integer and is expected to be encoded as a string");
let str = (<Str>val)._str;
//@ts-ignore
return <T>(val instanceof u64) ? U64.parseInt(str) : I64.parseInt(str);
}
assert(val instanceof Num, "Value with Key: "+ name + " with type " + nameof<T>() +" is not an Integer");
assert(val instanceof Num, "Value with Key: " + name + " with type " + nameof<T>() + " is not an Integer");
//@ts-ignore
return <T>(<Num>val)._num;
}
Expand All @@ -383,21 +378,21 @@ function decode<T, V = Uint8Array>(buf: V, name: string = ""): T {
//@ts-ignore
if (value instanceof Uint8Array ) {
//@ts-ignore
return base64.decode(getStr(val, name))
return base64.decode(getStr(val, name));
}
//@ts-ignore
// assert(val instanceof Arr, "Value with Key: " + name + " with type " + nameof<T>() + " is expected to be an array")
//@ts-ignore only checking the instance
return <T>decodeArray<valueof<T>>(val, name);
}
if (val instanceof Str){
if (val instanceof Str) {
//@ts-ignore
if (value instanceof u128) {
//@ts-ignore
return u128.fromString(getStr(val, name));
}
}
assert(val instanceof Obj, "Value with Key: " + name + " with type " + nameof<T>() + " is not an object or null")
assert(val instanceof Obj, "Value with Key: " + name + " with type " + nameof<T>() + " is not an object or null");
value = instantiate<T>();
//@ts-ignore
return value.decode<Obj>(<Obj>val);
Expand Down
2 changes: 1 addition & 1 deletion bindings/dist/transformerBundle.js

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions bindings/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,20 +173,21 @@ function __wrapper_${name}(): void {`);
if (toString(returnType) !== "void") {
this.sb.push(`
let encoder = new JSONEncoder();
let val: Uint8Array;
if ((isString<${returnTypeName}>() || isNullable<${returnTypeName}>()) && result == null) {
encoder.setNull(null);
val = encoder.serialize();
} else {
encode<${returnTypeName}>(encoder, result${hasNull ? "!" : ""}, null);
val = encode<${returnTypeName}>(result${hasNull ? "!" : ""}, null, encoder);
}
let val: Uint8Array = encoder.serialize();
value_return(val.byteLength, <usize>val.buffer);`);
}
this.sb.push(`}
export { __wrapper_${name} as ${name} }
`);
}

private typeName(type: TypeNode | ClassDeclaration): string {
if (!isClass(type)) {
return ASTBuilder.build(type);
Expand Down Expand Up @@ -251,20 +252,24 @@ export { __wrapper_${name} as ${name} }
return this;
}
encode(_encoder: JSONEncoder | null = null, name: string | null = ""): JSONEncoder {
_encode(name: string | null = "", _encoder: JSONEncoder | null = null): JSONEncoder {
let encoder = (_encoder != null ? _encoder : new JSONEncoder())!;
encoder.pushObject(name);
${createEncodeStatements(_class).join("\n ")}
encoder.popObject();
return encoder
return encoder;
}
encode(): Uint8Array {
return this._encode().serialize();
}
serialize(): Uint8Array {
return this.encode().serialize();
return this.encode();
}
toJSON(): string {
return this.encode().toString();
return this._encode().toString();
}
}`;
}
Expand Down Expand Up @@ -295,7 +300,7 @@ function createEncodeStatements(_class: ClassDeclaration): string[] {
(field: FieldDeclaration): string => {
let T = toString(field.type!);
let name = toString(field.name);
return `encode<${T}>(encoder, this.${name}, "${name}");`;
return `encode<${T}, JSONEncoder>(this.${name}, "${name}", encoder);`;
}
);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/asc.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/asc.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a8c363c

Please sign in to comment.