Skip to content

Commit be07c82

Browse files
committed
Fixes in the 1.0.0 kotlin migration guide
1 parent 5c9b94b commit be07c82

File tree

1 file changed

+59
-164
lines changed

1 file changed

+59
-164
lines changed

content/docs/migration_1.0/Kotlin.md

Lines changed: 59 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,6 @@ In 1.0.0. the previous example would instead now become:
7070
val encoding = Encoding.TEXT_JSON
7171
```
7272

73-
Custom encodings can be created by specifying an `id` and `suffix` string:
74-
75-
```kotlin
76-
val encoding = Encoding(id = 123, suffix = "example suffix")
77-
```
78-
7973
## Session-managed declarations
8074

8175
Up until 0.11.0, it was up to the user to keep track of their variable declarations to keep them alive, because once the variable declarations were garbage collected, the declarations were closed. This was because each Kotlin variable declaration is associated with a native Rust instance, and in order to avoid leaking the memory of that Rust instance, it was necessary to free it upon dropping the declaration instance. However, this behavior could be counterintuitive, as users were expecting the declaration to keep running despite losing track of the reference to it.
@@ -85,14 +79,16 @@ In this release we introduce a change in which any session declaration is intern
8579
For instance:
8680

8781
```kotlin
88-
val subscriber = session.declareSubscriber("A/B/C".intoKeyExpr(),
82+
val keyExprA = "A/B/C".intoKeyExpr().getOrThrow()
83+
val subscriber = session.declareSubscriber(keyExprA,
8984
callback = { sample -> println("Receiving sample on 'A/B/C': ${sample.payload}") }).getOrThrow()
9085

91-
session.declareSubscriber("A/C/D".intoKeyExpr(),
92-
callback = { sample -> println("Receiving sample on 'A/C/D': ${sample.payload}") }) // No variable is associated to the declared session, on 0.11.0 it would have been instantanely dropped
86+
val keyExprB = "A/C/D".intoKeyExpr().getOrThrow()
87+
session.declareSubscriber(keyExprB,
88+
callback = { sample -> println("Receiving sample on 'A/C/D': ${sample.payload}") }) // No variable is associated to the declared session, on 0.11.0 it would have been instantly dropped
9389
```
9490

95-
Therfore, when receiving a 'hello' message on `A/**` we would still see:
91+
Therefore, when receiving a 'hello' message on `A/**` we would still see:
9692

9793
```
9894
>> Receiving sample on 'A/B/C': hello
@@ -160,7 +156,7 @@ Changes:
160156

161157
## Reliability
162158

163-
The `Reliability` config parameter used on when declaring a subscriber, has been moved. It now must be specified when declaring a `Publisher` or when performing a `Put` or a `Delete` operaton.
159+
The `Reliability` config parameter used on when declaring a subscriber, has been moved. It now must be specified when declaring a `Publisher` or when performing a `Put` or a `Delete` operation.
164160

165161

166162
## Logging
@@ -202,202 +198,101 @@ We have created a new abstraction with the name of `ZBytes`. This class represen
202198
- `Value` is replaced by the combination of `ZBytes` and `Encoding`.
203199
- Replacing `ByteArray` to represent payloads
204200

205-
With `ZBytes` we have also introduced a Serialization and Deserialization for conveinent conversion between `ZBytes` and Kotlin types.
201+
With `ZBytes` we have also introduced a Serialization and Deserialization for convenient conversion between `ZBytes` and Kotlin types.
206202

207-
### Serialization
203+
### Serialization & Deserialization
208204

209205
We can serialize primitive types into a `ZBytes` instance, that is, converting the data into bytes processed by the zenoh network:
210206

211207
#### Primitive types
212208

213-
The following types support serialization:
209+
(De)Serialization is supported by the following primitive types:
214210

215-
* Numeric: `Byte`, `Short`, `Int`, `Long`, `Float` and `Double`.
211+
* Numeric: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `UByte`, `UShort`, `UInt` and `ULong`.
216212
* `String`
217213
* `ByteArray`
218214

219-
For the primitive types, there are three ways to serialize them into a `ZBytes`, for instance let's suppose
220-
we want to serialize an `Int`:
221-
222-
* using the `into()` syntax:
223-
```kotlin
224-
val exampleInt: Int = 256
225-
val zbytes: ZBytes = exampleInt.into()
226-
```
227-
228-
* using the `from()` syntax:
229-
```kotlin
230-
val exampleInt: Int = 256
231-
val zbytes: ZBytes = ZBytes.from(exampleInt)
232-
```
233-
234-
* using the serialize syntax:
215+
For instance:
235216
```kotlin
236217
val exampleInt: Int = 256
237-
val zbytes: ZBytes = ZBytes.serialize<Int>(exampleInt).getOrThrow()
218+
val zbytes: ZBytes = zSerialize<Int>(exampleInt).getOrThrow()
219+
val deserialization = zDeserialize<Int>(zbytes).getOrThrow()
220+
check(exampleInt == deserialization)
238221
```
222+
239223
This approach works as well for the other aforementioned types.
240224

241-
Using `into()` or `from()` guarantees successful serialization for implemented types.
242-
Using `serialize` requires a generic parameter, and returns a Result, i.e. it can fail based in the type passed in and contents of the input parameter.
225+
For serialization, `String` and `ByteArray` the functions `ZBytes::from(string: String)` and `ZBytes::from(bytes: ByteArray)` can be used respectively. Analogously, deserialization, `ZBytes::toString()` and `ZBytes::toByteArray()` can be used.
243226

244227
#### Lists
245228

246229
Lists are supported, but they must be either:
247-
- List of `Number` : (`Byte`, `Short`, `Int`, `Long`, `Float`, `Double`)
230+
- List of numeric types : (`Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `UByte`, `UShort`, `UInt` and `ULong`)
248231
- List of `String`
249232
- List of `ByteArray`
250-
- List of `IntoZBytes`
233+
- List of another supported type
251234

252235
The serialize syntax must be used:
253236
```kotlin
254237
val myList = listOf(1, 2, 5, 8, 13, 21)
255-
val zbytes = ZBytes.serialize<List<Int>>(myList).getOrThrow()
238+
val zbytes = zSerialize<List<Int>>(myList).getOrThrow()
239+
val outputList = zDeserialize<List<Int>>(zbytes).getOrThrow()
240+
check(myList == outputList)
256241
```
257242

258243
#### Maps
259244

260245
Maps are supported as well, with the restriction that their inner types must supported primitives:
261-
- `Number`
246+
- Numeric types
262247
- `String`
263248
- `ByteArray`
264-
- `IntoZBytes`
249+
- Map of another supported types
265250

266251
```kotlin
267252
val myMap: Map<String, Int> = mapOf("foo" to 1, "bar" to 2)
268-
val zbytes = ZBytes.serialize<Map<String, Int>>(myMap).getOrThrow()
253+
val zbytes = zSerialize<Map<String, Int>>(myMap).getOrThrow()
254+
val outputMap = zDeserialize<Map<String, Int>>(zbytes).getOrThrow()
255+
output(myMap == outputMap)
269256
```
270257

271-
### Deserialization
258+
#### Pair & Triple
272259

273-
#### Primitive types
274-
275-
* Numeric: `Byte`, `Short`, `Int`, `Long`, `Float` and `Double`
276-
* `String`
277-
* `ByteArray`
278-
279-
Example:
280-
281-
For these primitive types, you can use the functions `to<Type>`, that is
282-
- `toByte`
283-
- `toShort`
284-
- `toInt`
285-
- `toLong`
286-
- `toDouble`
287-
- `toString`
288-
- `toByteArray`
289-
290-
For instance, for an Int:
291-
```kotlin
292-
val example: Int = 256
293-
val zbytes: ZBytes = exampleInt.into()
294-
val deserializedInt = zbytes.toInt()
295-
```
296-
297-
Alternatively, the deserialize syntax can be used as well:
298-
```kotlin
299-
val exampleInt: Int = 256
300-
val zbytes: ZBytes = exampleInt.into()
301-
val deserializedInt = zbytes.deserialize<Int>().getOrThrow()
302-
```
303-
304-
#### Lists
305-
306-
Lists are supported, but they must be deserialized into inner primitive types:
307-
- List of `Number` (`Byte`, `Short`, `Int`, `Long`, `Float` or `Double`)
308-
- List of `String`
309-
- List of `ByteArray`
310-
311-
To deserialize into a list, use the deserialize syntax as follows:
312-
```kotlin
313-
val inputList = listOf("sample1", "sample2", "sample3")
314-
payload = ZBytes.serialize(inputList).getOrThrow()
315-
val outputList = payload.deserialize<List<String>>().getOrThrow()
316-
```
317-
318-
#### Maps
319-
320-
Maps are supported as well, with the restriction that their inner types must be one of the following:
321-
- `Number`
322-
- `String`
323-
- `ByteArray`
324-
325-
```kotlin
326-
val inputMap = mapOf("key1" to "value1", "key2" to "value2", "key3" to "value3")
327-
payload = ZBytes.serialize(inputMap).getOrThrow()
328-
val outputMap = payload.deserialize<Map<String, String>>().getOrThrow()
329-
check(inputMap == outputMap)
330-
```
331-
332-
### Custom serialization and deserialization
333-
334-
#### Serialization
335-
336-
For a user defined class, the class must implement the `IntoZBytes` interface.
337-
For instance:
338-
339-
```kotlin
340-
class Foo(val content: String) : IntoZBytes {
341-
342-
/*Inherits: IntoZBytes*/
343-
override fun into(): ZBytes = content.into()
344-
}
345-
```
346-
347-
This way, we can do:
348-
```kotlin
349-
val foo = Foo("bar")
350-
val serialization = ZBytes.serialize<Foo>(foo).getOrThrow()
351-
```
352-
353-
Implementing the `IntoZBytes` interface on a class allows serializing lists and maps of that type, for instance:
354-
```kotlin
355-
val list = listOf(Foo("bar"), Foo("buz"), Foo("fizz"))
356-
val zbytes = ZBytes.serialize<List<Foo>>(list)
357-
```
358-
359-
#### Deserialization
360-
361-
Regarding deserialization for custom objects, for the time being (this API will be expanded to
362-
provide further utilities) you need to manually convert the ZBytes into the type you want.
363-
364-
```kotlin
365-
val inputFoo = Foo("example")
366-
payload = ZBytes.serialize(inputFoo).getOrThrow()
367-
val outputFoo = Foo.from(payload)
368-
check(inputFoo == outputFoo)
369-
370-
// List of Foo.
371-
val inputListFoo = inputList.map { value -> Foo(value) }
372-
payload = ZBytes.serialize<List<Foo>>(inputListFoo).getOrThrow()
373-
val outputListFoo = payload.deserialize<List<ZBytes>>().getOrThrow().map { zbytes -> Foo.from(zbytes) }
374-
check(inputListFoo == outputListFoo)
375-
376-
// Map of Foo.
377-
val inputMapFoo = inputMap.map { (k, v) -> Foo(k) to Foo(v) }.toMap()
378-
payload = ZBytes.serialize<Map<Foo, Foo>>(inputMapFoo).getOrThrow()
379-
val outputMapFoo = payload.deserialize<Map<ZBytes, ZBytes>>().getOrThrow()
380-
.map { (key, value) -> Foo.from(key) to Foo.from(value) }.toMap()
381-
check(inputMapFoo == outputMapFoo)
382-
```
260+
Similarly,
261+
- Pair:
262+
```kotlin
263+
val input: Pair<String, Int> = Pair("one", 1)
264+
val zbytes = zSerialize(input).getOrThrow()
265+
val output: Pair<String, Int> = zDeserialize(zbytes).getOrThrow()
266+
check(input == output)
267+
```
383268

384-
##### Deserialization functions:
269+
- Triple:
270+
```kotlin
271+
val input: Triple<String, Int, Boolean> = Triple("one", 1, true)
272+
val zbytes = zSerialize(input).getOrThrow()
273+
val output: Triple<String, Int, Boolean> = zDeserialize(zbytes).getOrThrow()
274+
check(input == output)
275+
```
385276

386-
As an alternative, the `deserialize` function admits an argument which by default is an emptyMap, consisting
387-
of a `Map<KType, KFunction1<ZBytes, Any>>` map.
277+
#### Parameterized types combinations
388278

389-
For instance, the previous implementation of our example Foo class.
390-
We could provide directly the deserialization function as follows:
279+
Combinations of all the above types is supported. For instance:
391280

392-
```kotlin
393-
fun deserializeFoo(zbytes: ZBytes): Foo {
394-
return Foo(zbytes.toString())
395-
}
281+
- List of lists
282+
```kotlin
283+
val input: List<List<Int>> = listOf(listOf(1, 2, 3))
284+
val zbytes = zSerialize(input).getOrThrow()
285+
val output = zDeserialize<List<List<Int>>>(zbytes).getOrThrow()
286+
check(input == output)
287+
```
396288

397-
val foo = Foo("bar")
398-
val zbytes = ZBytes.serialize<Foo>(foo)
399-
val deserialization = zbytes.deserialize<Foo>(mapOf(typeOf<Foo>() to ::deserializeFoo)).getOrThrow()
400-
```
289+
- List of maps
290+
```kotlin
291+
val input: List<Map<String, Int>> = listOf(mapOf("a" to 1, "b" to 2))
292+
val zbytes = zSerialize(input).getOrThrow()
293+
val output = zDeserialize<List<Map<String, Int>>>(zbytes).getOrThrow()
294+
check(input == output)
295+
```
401296

402297
## Reply handling
403298

0 commit comments

Comments
 (0)