Skip to content

Commit

Permalink
Adding candid converter
Browse files Browse the repository at this point in the history
  • Loading branch information
skilesare committed Jan 5, 2023
1 parent f46a585 commit d399b8b
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 18 deletions.
2 changes: 1 addition & 1 deletion dfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"packtool": "vessel sources"
}
},
"dfx": "0.9.3",
"dfx": "0.12.1",
"networks": {
"local": {
"bind": "127.0.0.1:8000",
Expand Down
31 changes: 16 additions & 15 deletions package-set.dhall
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,22 @@ let Package =
let
-- This is where you can add your own packages to the package-set
additions =
[] : List Package
[{ name = "candid"
, version = "v1.0.1"
, repo = "https://github.com/gekctek/motoko_candid"
, dependencies = ["xtendedNumbers", "base"] : List Text
},
{ name = "xtendedNumbers"
, version = "v1.0.2"
, repo = "https://github.com/gekctek/motoko_numbers"
, dependencies = [] : List Text
}] : List Package

let
{- This is where you can override existing packages in the package-set
For example, if you wanted to use version `v2.0.0` of the foo library:
let overrides = [
{ name = "foo"
, version = "v2.0.0"
, repo = "https://github.com/bar/foo"
let overrides =
[{name = "base"
, version = "moc-0.7.4"
, repo = "https://github.com/dfinity/motoko-base"
, dependencies = [] : List Text
}
]
-}
overrides =
[] : List Package
}]

in upstream # additions # overrides
in upstream # additions # overrides
174 changes: 174 additions & 0 deletions src/candid.mo
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@

import Buffer "mo:base/Buffer";
import Nat "mo:base/Nat";
import Nat16 "mo:base/Nat16";
import Nat32 "mo:base/Nat32";
import Nat64 "mo:base/Nat64";
import Nat8 "mo:base/Nat8";
import Float "mo:base/Float";
import Int "mo:base/Int";
import Int8 "mo:base/Int8";
import Int16 "mo:base/Int16";
import Int32 "mo:base/Int32";
import Int64 "mo:base/Int64";
import Bool "mo:base/Bool";
import Blob "mo:base/Blob";
import Principal "mo:base/Principal";
import Text "mo:base/Text";

import Types "types";
import CandyHex "hex";

import CandidTypes "mo:candid/Type";
import Arg "mo:candid/Arg";
import Value "mo:candid/Value";


module {
//convert a candy value to JSON
public func value_to_candid(val: Types.CandyValue): [Arg.Arg] {

let buffer = Buffer.Buffer<Arg.Arg>(0);

switch(val){
//nat
case(#Nat(val)) buffer.add({_type = #nat; value = #nat(val)});
case(#Nat64(val)) buffer.add({_type = #nat64; value = #nat64(val)});
case(#Nat32(val)) buffer.add({_type = #nat32; value = #nat32(val)});
case(#Nat16(val)) buffer.add({_type = #nat16; value = #nat16(val)});
case(#Nat8(val)) buffer.add({_type = #nat8; value = #nat8(val)});
//text
case(#Text(val)) buffer.add({_type = #text; value = #text(val)});
//class
case(#Class(val)){
let types: Buffer.Buffer<CandidTypes.RecordFieldType> = Buffer.Buffer<CandidTypes.RecordFieldType>(val.size());
let body: Buffer.Buffer<Value.RecordFieldValue> = Buffer.Buffer<Value.RecordFieldValue>(val.size());
for(this_item in val.vals()){
types.add({tag = #name(this_item.name); _type = (value_to_candid(this_item.value))[0]._type});
body.add({tag = #name(this_item.name); value = (value_to_candid(this_item.value))[0].value});
};
buffer.add({_type=#record(types.toArray()); value = #record(body.toArray())})
};
//array
case(#Array(val)){
let list = switch(val){
case(#frozen(val)) val;
case(#thawed(val)) val;
};
var bFoundMultipleTypes = false;
var lastType : ?CandidTypes.Type = null;
let values: Buffer.Buffer<Value.Value> = Buffer.Buffer<Value.Value>(list.size());
let types: Buffer.Buffer<CandidTypes.RecordFieldType> = Buffer.Buffer<CandidTypes.RecordFieldType>(list.size());
let body: Buffer.Buffer<Value.RecordFieldValue> = Buffer.Buffer<Value.RecordFieldValue>(list.size());
var tracker : Nat32 = 0;
for(this_item in list.vals()){
let item = (value_to_candid(this_item))[0];
switch(lastType){
case(null) lastType := ?item._type;
case(?lastType){
if(CandidTypes.equal(lastType, item._type)){

} else {
bFoundMultipleTypes := true;
};
};
};
types.add({_type = item._type; tag = #hash(tracker)});
body.add({tag = #hash(tracker); value = item.value});
values.add(item.value);
tracker += 1;
};

if(bFoundMultipleTypes){
//need to make a record
buffer.add({_type=#record(types.toArray()); value = #record(body.toArray())})
} else {
let thisType = switch(lastType){
case(null) #_null ;
case(?val) val ;
};
buffer.add({_type=#vector(thisType); value = #vector(values.toArray())});
};

};
case(#Option(val)){
switch(val){
case(null){
buffer.add({_type = #opt(#_null); value = #_null});
};
case(?val){
let item = (value_to_candid(val))[0];
buffer.add({_type = #opt(item._type); value = #opt(?item.value)});
};
};
};
case(#Nats(val)){
let list = switch(val){
case(#frozen(val)) val;
case(#thawed(val)) val;
};

let values: Buffer.Buffer<Value.Value> = Buffer.Buffer<Value.Value>(list.size());
for(this_item in list.vals()){
values.add(#nat(this_item));
};
buffer.add({_type=#vector(#nat); value = #vector(values.toArray())});
};
case(#Floats(val)){
let list = switch(val){
case(#frozen(val)) val;
case(#thawed(val)) val;
};

let values: Buffer.Buffer<Value.Value> = Buffer.Buffer<Value.Value>(list.size());
for(this_item in list.vals()){
values.add(#float64(this_item));
};

buffer.add({_type=#vector(#float64); value = #vector(values.toArray())});
};
//bytes
case(#Bytes(val)){
let list = switch(val){
case(#frozen(val)) val;
case(#thawed(val)) val;
};

let values: Buffer.Buffer<Value.Value> = Buffer.Buffer<Value.Value>(list.size());
for(this_item in list.vals()){
values.add(#nat8(this_item));
};

buffer.add({_type=#vector(#nat8); value = #vector(values.toArray())});
};
//bytes
case(#Blob(val)){

let list = Blob.toArray(val);

let values: Buffer.Buffer<Value.Value> = Buffer.Buffer<Value.Value>(list.size());
for(this_item in list.vals()){
values.add(#nat8(this_item));
};

buffer.add({_type=#vector(#nat8); value = #vector(values.toArray())});

};
//principal
case(#Principal(val)) buffer.add({_type = #principal; value = #principal(#transparent(val))});
//bool
case(#Bool(val))buffer.add({_type = #bool; value = #bool(val)});

//float
case(#Float(val))buffer.add({_type = #float64; value = #float64(val)});
case(#Empty)buffer.add({_type = #empty; value = #empty});
case(#Int(val))buffer.add({_type = #int; value = #int(val)});
case(#Int64(val))buffer.add({_type = #int64; value = #int64(val)});
case(#Int32(val))buffer.add({_type = #int32; value = #int32(val)});
case(#Int16(val))buffer.add({_type = #int16; value = #int16(val)});
case(#Int8(val))buffer.add({_type = #int8; value = #int8(val)});
};

buffer.toArray();
};
};
1 change: 1 addition & 0 deletions tests/test_runner.mo
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Clone "../src/clone";
import Conversion "../src/conversion";
import Properties "../src/properties";
import Workspace "../src/workspace";
import Candid "../src/candid";



Expand Down
4 changes: 2 additions & 2 deletions vessel.dhall
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
dependencies = [ "base", "matchers" ],
compiler = None Text
dependencies = [ "base", "matchers", "candid", "xtendedNumbers"],
compiler = Some "0.7.4"
}

0 comments on commit d399b8b

Please sign in to comment.