From d399b8ba1d2e9b3dacea26e470fb90921b06c454 Mon Sep 17 00:00:00 2001 From: Austin Fatheree Date: Wed, 4 Jan 2023 18:02:49 -0600 Subject: [PATCH] Adding candid converter --- dfx.json | 2 +- package-set.dhall | 31 ++++---- src/candid.mo | 174 +++++++++++++++++++++++++++++++++++++++++++ tests/test_runner.mo | 1 + vessel.dhall | 4 +- 5 files changed, 194 insertions(+), 18 deletions(-) create mode 100644 src/candid.mo diff --git a/dfx.json b/dfx.json index 4d4a0df..c5ec53c 100644 --- a/dfx.json +++ b/dfx.json @@ -12,7 +12,7 @@ "packtool": "vessel sources" } }, - "dfx": "0.9.3", + "dfx": "0.12.1", "networks": { "local": { "bind": "127.0.0.1:8000", diff --git a/package-set.dhall b/package-set.dhall index 072bbde..c54e930 100644 --- a/package-set.dhall +++ b/package-set.dhall @@ -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 \ No newline at end of file diff --git a/src/candid.mo b/src/candid.mo new file mode 100644 index 0000000..2b7e81b --- /dev/null +++ b/src/candid.mo @@ -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(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 = Buffer.Buffer(val.size()); + let body: Buffer.Buffer = Buffer.Buffer(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 = Buffer.Buffer(list.size()); + let types: Buffer.Buffer = Buffer.Buffer(list.size()); + let body: Buffer.Buffer = Buffer.Buffer(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 = Buffer.Buffer(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 = Buffer.Buffer(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 = Buffer.Buffer(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 = Buffer.Buffer(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(); + }; +}; \ No newline at end of file diff --git a/tests/test_runner.mo b/tests/test_runner.mo index 4f1ce89..545835a 100644 --- a/tests/test_runner.mo +++ b/tests/test_runner.mo @@ -11,6 +11,7 @@ import Clone "../src/clone"; import Conversion "../src/conversion"; import Properties "../src/properties"; import Workspace "../src/workspace"; +import Candid "../src/candid"; diff --git a/vessel.dhall b/vessel.dhall index 19be4cd..1d7c8b6 100644 --- a/vessel.dhall +++ b/vessel.dhall @@ -1,4 +1,4 @@ { - dependencies = [ "base", "matchers" ], - compiler = None Text + dependencies = [ "base", "matchers", "candid", "xtendedNumbers"], + compiler = Some "0.7.4" }