Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Rust] Subtyping support for deserialization #211

Merged
merged 55 commits into from
Apr 22, 2021
Merged
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
b68d526
refactor deserialization
chenyan-dfinity Mar 23, 2021
6f80299
checkpoint
chenyan-dfinity Mar 27, 2021
1a133c4
checkpoint
chenyan-dfinity Mar 27, 2021
7628acc
fix
chenyan-dfinity Mar 27, 2021
8e8a81f
fix
chenyan-dfinity Mar 28, 2021
1ce2b1c
fix
chenyan-dfinity Mar 28, 2021
74f6729
first stab at deserialization
chenyan-dfinity Mar 29, 2021
b57ea04
int
chenyan-dfinity Mar 29, 2021
20a1280
anyhow
chenyan-dfinity Mar 30, 2021
6c0d2e3
fix anyhow
chenyan-dfinity Mar 30, 2021
5efe8f5
subtype
chenyan-dfinity Mar 31, 2021
4768588
fix
chenyan-dfinity Apr 1, 2021
ba0a80f
opt
chenyan-dfinity Apr 2, 2021
5b9f940
vec
chenyan-dfinity Apr 2, 2021
3c05675
fix
chenyan-dfinity Apr 2, 2021
46643f8
struct, skipping not tested
chenyan-dfinity Apr 2, 2021
a1bc18b
enum
chenyan-dfinity Apr 3, 2021
df2e7ab
connect tests
chenyan-dfinity Apr 3, 2021
2ed9531
move macros into utils.rs
chenyan-dfinity Apr 3, 2021
a81fc29
str
chenyan-dfinity Apr 3, 2021
d2dde04
fix
chenyan-dfinity Apr 3, 2021
e036c58
fix
chenyan-dfinity Apr 3, 2021
e6a7c6f
primitive types
chenyan-dfinity Apr 4, 2021
3241858
principal
chenyan-dfinity Apr 4, 2021
90d65bf
tuple
chenyan-dfinity Apr 4, 2021
d0fd52b
i128
chenyan-dfinity Apr 4, 2021
b7d8b82
map
chenyan-dfinity Apr 4, 2021
4e12303
bytes
chenyan-dfinity Apr 5, 2021
59e6901
fix
chenyan-dfinity Apr 5, 2021
1b1dd62
fix perf
chenyan-dfinity Apr 5, 2021
8403128
fix
chenyan-dfinity Apr 5, 2021
997b023
subtype error message
chenyan-dfinity Apr 5, 2021
3aaf583
fix test
chenyan-dfinity Apr 5, 2021
60c96c1
more expect values
chenyan-dfinity Apr 6, 2021
e0d4e6c
fix untyped idlvalue
chenyan-dfinity Apr 6, 2021
c532288
Merge remote-tracking branch 'origin/master' into binread
chenyan-dfinity Apr 6, 2021
f73f873
revert to byteorder
chenyan-dfinity Apr 6, 2021
3dc3e13
checkpoint
chenyan-dfinity Apr 7, 2021
aaee7a2
skip
chenyan-dfinity Apr 7, 2021
ce5620b
option
chenyan-dfinity Apr 7, 2021
7c694f4
Merge remote-tracking branch 'origin/master' into binread
chenyan-dfinity Apr 7, 2021
fb05a00
omit _ field for IDLValue
chenyan-dfinity Apr 11, 2021
8952073
fix variant index
chenyan-dfinity Apr 11, 2021
2b91323
fix test
chenyan-dfinity Apr 12, 2021
5eabe19
reference
chenyan-dfinity Apr 12, 2021
8a8d805
fix test
chenyan-dfinity Apr 12, 2021
c53a050
lint
chenyan-dfinity Apr 12, 2021
5978024
update test
chenyan-dfinity Apr 12, 2021
4cebae4
detect empty struct
chenyan-dfinity Apr 12, 2021
cd68644
remove nest record counter
chenyan-dfinity Apr 12, 2021
1a22645
Merge remote-tracking branch 'origin/master' into binread
chenyan-dfinity Apr 13, 2021
09317a7
Merge remote-tracking branch 'origin/master' into binread
chenyan-dfinity Apr 14, 2021
dacbf31
fix annotate type
chenyan-dfinity Apr 20, 2021
f8cb89a
update test
chenyan-dfinity Apr 20, 2021
e93285f
test for vec{}
chenyan-dfinity Apr 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix test
chenyan-dfinity committed Apr 12, 2021
commit 8a8d805fd65856eec3483d56df74734965a65f13
31 changes: 18 additions & 13 deletions rust/candid/src/de.rs
Original file line number Diff line number Diff line change
@@ -805,19 +805,24 @@ impl<'de, 'a> de::MapAccess<'de> for Compound<'a, 'de> {
} => {
match (expect.front(), wire.front()) {
(Some(e), Some(w)) => {
if e.id.get_id() == w.id.get_id() {
self.de.set_field_name(e.id.clone());
self.de.expect_type = expect.pop_front().unwrap().ty;
self.de.wire_type = wire.pop_front().unwrap().ty;
} else if e.id.get_id() < w.id.get_id() {
// by subtyping rules, expect_type can only be opt, reserved or null.
self.de.set_field_name(e.id.clone());
self.de.expect_type = expect.pop_front().unwrap().ty;
self.de.wire_type = Type::Reserved;
} else {
self.de.set_field_name(Label::Named("_".to_owned()));
self.de.wire_type = wire.pop_front().unwrap().ty;
self.de.expect_type = Type::Reserved;
use std::cmp::Ordering;
match e.id.get_id().cmp(&w.id.get_id()) {
Ordering::Equal => {
self.de.set_field_name(e.id.clone());
self.de.expect_type = expect.pop_front().unwrap().ty;
self.de.wire_type = wire.pop_front().unwrap().ty;
}
Ordering::Less => {
// by subtyping rules, expect_type can only be opt, reserved or null.
self.de.set_field_name(e.id.clone());
self.de.expect_type = expect.pop_front().unwrap().ty;
self.de.wire_type = Type::Reserved;
}
Ordering::Greater => {
self.de.set_field_name(Label::Named("_".to_owned()));
self.de.wire_type = wire.pop_front().unwrap().ty;
self.de.expect_type = Type::Reserved;
}
}
}
(None, Some(_)) => {
10 changes: 5 additions & 5 deletions rust/candid/src/utils.rs
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ macro_rules! Decode {
///
/// ```
/// # use candid::Encode;
/// # use candid::de::decode_args;
/// # use candid::decode_args;
/// let golden1 = 123u64;
/// let golden2 = "456";
/// let bytes = Encode!(&golden1, &golden2).unwrap();
@@ -69,7 +69,7 @@ where
///
/// ```
/// # use candid::Encode;
/// # use candid::de::decode_one;
/// # use candid::decode_one;
/// let golden1 = 123u64;
/// let bytes = Encode!(&golden1).unwrap();
/// let value1: u64 = decode_one(&bytes).unwrap();
@@ -88,7 +88,7 @@ where
///
/// ```
/// # use candid::Decode;
/// # use candid::ser::write_args;
/// # use candid::write_args;
/// let golden1 = 1u64;
/// let golden2 = "hello";
/// let mut buffer = Vec::new();
@@ -111,7 +111,7 @@ pub fn write_args<Tuple: ArgumentEncoder, Writer: std::io::Write>(
///
/// ```
/// # use candid::Decode;
/// # use candid::ser::encode_args;
/// # use candid::encode_args;
/// let golden1 = 1u64;
/// let golden2 = "hello";
/// let buffer = encode_args((golden1, golden2)).unwrap();
@@ -130,7 +130,7 @@ pub fn encode_args<Tuple: ArgumentEncoder>(arguments: Tuple) -> Result<Vec<u8>>
///
/// ```
/// # use candid::Decode;
/// # use candid::ser::encode_one;
/// # use candid::encode_one;
/// let golden = "hello";
/// let buffer = encode_one(golden).unwrap();
///
8 changes: 4 additions & 4 deletions test/reference.test.did
Original file line number Diff line number Diff line change
@@ -55,9 +55,9 @@ assert blob "DIDL\00\01\6a\01\03\ca\ff\ee\01\61" !: (func () -> ()) "func: no
assert blob "DIDL\01\6a\01\69\01\7d\00\01\00\01\01\03\ca\ff\ee\03foo" !: (func (service {}) -> (nat)) "func: service not in type table";
assert blob "DIDL\01\6a\01\71\01\7d\01\03\01\00\01\01\03\ca\ff\ee\03foo" !: (func (text) -> (nat)) "func: invalid annotation";

// coercion does not look at type table
assert blob "DIDL\01\69\00\01\00\01\03\ca\ff\ee" == "(service \"w7x7r-cok77-xa\")" : (service { foo : (text) -> (nat) }) "service {} decodes at service { foo : (text) -> (nat) }";
// subtype
assert blob "DIDL\01\69\00\01\00\01\03\ca\ff\ee" !: (service { foo : (text) -> (nat) }) "service {} !<: service { foo : (text) -> (nat) }";
assert blob "DIDL\02\6a\01\71\01\7d\00\69\01\03foo\00\01\01\01\03\ca\ff\ee" == "(service \"w7x7r-cok77-xa\")" : (service {}) "service { foo : (text) -> (nat) } decodes at service {}";

assert blob "DIDL\01\6a\00\00\00\01\00\01\01\03\ca\ff\ee\03foo" == "(func \"w7x7r-cok77-xa\".foo)" : (func (text) -> (nat)) "func () -> () decodes at func (text) -> (nat) }";
assert blob "DIDL\01\6a\01\71\01\7d\00\01\00\01\01\03\ca\ff\ee\03foo" == "(func \"w7x7r-cok77-xa\".foo)" : (func () -> ()) "func (text) -> (nat) decodes at func () -> () }";
assert blob "DIDL\01\6a\00\00\00\01\00\01\01\03\ca\ff\ee\03foo" !: (func (text) -> (nat)) "func () -> () !<: (text) -> (nat) }";
assert blob "DIDL\01\6a\01\71\01\7d\00\01\00\01\01\03\ca\ff\ee\03foo" == "(func \"w7x7r-cok77-xa\".foo)" : (func (text, opt text) -> ()) "func (text) -> (nat) decodes at func () -> () }";