You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pages/storey/containers/map/key-impl.mdx
+25-11Lines changed: 25 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -9,6 +9,7 @@ import { Callout } from "nextra/components";
9
9
In this section, we will implement a custom key type for use with [maps].
10
10
11
11
Let's say we have a `Denom` enum to represent different kinds of tokens:
12
+
12
13
- native tokens
13
14
-[CW20] tokens
14
15
@@ -40,13 +41,17 @@ impl Key for Denom {
40
41
}
41
42
```
42
43
43
-
The [`Kind`] associated type is used to signal to the framework whether the key is dynamically sized or not. In this case, we use [`DynamicKey`] because the key size is not fixed.
44
-
If it was always exactly 8 bytes, we could use [`FixedSizeKey<8>`] instead.
44
+
The [`Kind`] associated type is used to signal to the framework whether the key is dynamically sized
45
+
or not. In this case, we use [`DynamicKey`] because the key size is not fixed. If it was always
46
+
exactly 8 bytes, we could use [`FixedSizeKey<8>`] instead.
45
47
46
48
<Callout>
47
49
Why does this matter? The framework uses this information to determine how to encode the key. If there are more keys following this one (e.g. in a multi-level map), the framework needs to know how to tell where this one ends during decoding.
48
50
49
-
For a dynamically sized key, the framework will length-prefix it when necessary. For a fixed-size key, it will use the static information you provide with `FixedSizeKey<L>` to figure out how many bytes to eat - a more performant solution.
51
+
For a dynamically sized key, the framework will length-prefix it when necessary. For a fixed-size
52
+
key, it will use the static information you provide with `FixedSizeKey<L>` to figure out how many
53
+
bytes to eat - a more performant solution.
54
+
50
55
</Callout>
51
56
52
57
The [`encode`] method is used to serialize the key into a byte vector. Let's implement it now!
@@ -77,9 +82,12 @@ impl Key for Denom {
77
82
}
78
83
```
79
84
80
-
The code should be pretty self-explanatory. We use a simple encoding scheme where we write a single byte discriminant followed by the actual data. The discriminant is how we tell a native token from a CW20 token.
85
+
The code should be pretty self-explanatory. We use a simple encoding scheme where we write a single
86
+
byte discriminant followed by the actual data. The discriminant is how we tell a native token from a
87
+
CW20 token.
81
88
82
-
One little improvement we can go for is to avoid hardcoding the discriminant. We'll want to reuse these values in the decoding logic, so let's define them as constants:
89
+
One little improvement we can go for is to avoid hardcoding the discriminant. We'll want to reuse
90
+
these values in the decoding logic, so let's define them as constants:
Alright. The `Key` trait allows us to access the data in a map using our custom key type. We still need a way to decode the key back into the enum. This is used for example in iteration.
123
+
Alright. The `Key` trait allows us to access the data in a map using our custom key type. We still
124
+
need a way to decode the key back into the enum. This is used for example in iteration.
116
125
117
126
## The OwnedKey trait
118
127
@@ -164,15 +173,18 @@ impl OwnedKey for Denom {
164
173
}
165
174
```
166
175
167
-
The [`from_bytes`] method should return an instance of the key type or an error if the data is invalid. Here it does the following:
176
+
The [`from_bytes`] method should return an instance of the key type or an error if the data is
177
+
invalid. Here it does the following:
178
+
168
179
- read the discriminant byte
169
180
- read the data bytes as a UTF-8 string, erroring out if it's not valid
170
181
- match the discriminant to the enum variant, or error if invalid
171
182
- return the deserialized key
172
183
173
184
<Callout>
174
-
What we have is functional. There's one last improvement you could make here - a proper error type. We used `()` as a placeholder, but in production code it's good practice to define an enum. In this case, the enum could hold variants
175
-
like `InvalidDiscriminant` and `InvalidUTF8`.
185
+
What we have is functional. There's one last improvement you could make here - a proper error
186
+
type. We used `()` as a placeholder, but in production code it's good practice to define an enum.
187
+
In this case, the enum could hold variants like `InvalidDiscriminant` and `InvalidUTF8`.
176
188
</Callout>
177
189
178
190
## Using the thing
@@ -247,7 +259,9 @@ Voilà! It works just like it would with any other key.
0 commit comments