Nir
07/16/2020, 3:58 PMTobias Berger
07/16/2020, 4:51 PMNir
07/16/2020, 5:19 PMNir
07/16/2020, 5:19 PMNir
07/16/2020, 5:20 PMNir
07/16/2020, 5:20 PMNir
07/16/2020, 5:21 PMTobias Berger
07/16/2020, 5:22 PMNir
07/16/2020, 5:22 PMNir
07/16/2020, 5:22 PMTobias Berger
07/16/2020, 5:23 PMNir
07/16/2020, 5:23 PMNir
07/16/2020, 5:23 PMTobias Berger
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:25 PMNir
07/16/2020, 5:26 PMNir
07/16/2020, 5:26 PMNir
07/16/2020, 5:28 PMTobias Berger
07/16/2020, 5:28 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:29 PMNir
07/16/2020, 5:30 PMNir
07/16/2020, 5:30 PMNir
07/16/2020, 5:31 PMNir
07/16/2020, 5:31 PMFleshgrinder
07/16/2020, 7:14 PMFleshgrinder
07/16/2020, 7:15 PMNir
07/16/2020, 7:18 PMNir
07/16/2020, 7:19 PMNir
07/16/2020, 7:19 PMNir
07/16/2020, 7:20 PMNir
07/16/2020, 7:20 PMNir
07/16/2020, 7:22 PMNir
07/16/2020, 7:23 PMinline class foo(val x: Int) : Int by x
gives me a pile of errors basicallyFleshgrinder
07/16/2020, 7:25 PMobject works.Nir
07/16/2020, 7:25 PMNir
07/16/2020, 7:26 PMclass foo(val x: Int) : Int by x does not work eitherFleshgrinder
07/16/2020, 7:30 PMInt isn't an interface, hence, it cannot work. Number would. Gimme a sec, I'll prepare an example.
In Rust terms: you are trying to impl i32 for foo which isn't possible there either.Fleshgrinder
07/16/2020, 7:33 PMFleshgrinder
07/16/2020, 7:33 PMC is from a different library.Nir
07/16/2020, 7:34 PMNir
07/16/2020, 7:34 PMFleshgrinder
07/16/2020, 7:34 PMNir
07/16/2020, 7:35 PMFleshgrinder
07/16/2020, 7:35 PMNumber is an abstract class but that's close enough I'd say (since you CAN extend it).Nir
07/16/2020, 7:35 PMNir
07/16/2020, 7:36 PMsealed class JsonData {
class IntWrapper(val x: Int) : JsonData()
class StringWrapper(val x: String) : JsonData()
class ListWrapper(val x: JsonArray) : JsonData()
class ObjectWrapper(val x: JsonObject) : JsonData()
class NullWrapper() : JsonData()
}Fleshgrinder
07/16/2020, 7:36 PMInt to Number works but not String to Number.Nir
07/16/2020, 7:36 PMJsonValue with a member var jsonData: JsonDataNir
07/16/2020, 7:37 PMclass glug(val x: Int) : Number by xNir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMNir
07/16/2020, 7:37 PMFleshgrinder
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMFleshgrinder
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMNir
07/16/2020, 7:38 PMcompanion object {
fun make(x: Int): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.IntWrapper(x)
return j
}
fun make(x: String): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.StringWrapper(x)
return j
}
inline fun <reified T> make(x: List<T>): JsonValue {
val j = JsonValue()
j.jsonData = JsonData.ListWrapper(x.map { JsonValue.make(it) })
return j
}
}Nir
07/16/2020, 7:38 PMNir
07/16/2020, 7:39 PMmake function to work for List<Int>, List<String>, and so onNir
07/16/2020, 7:39 PMFleshgrinder
07/16/2020, 7:39 PMNir
07/16/2020, 7:39 PMNir
07/16/2020, 7:39 PMNir
07/16/2020, 7:40 PMNir
07/16/2020, 7:40 PMmake function doesn't call itself recursively then it's not going to work in the ideal wayNir
07/16/2020, 7:41 PMNir
07/16/2020, 7:41 PMmake to properly work, including recursively, for built in typesNir
07/16/2020, 7:41 PMNir
07/16/2020, 7:42 PMmakeNir
07/16/2020, 7:42 PMNir
07/16/2020, 7:42 PMfun make(data: Any?): JsonValue {
val j = JsonValue()
if (data is Int) {
j.jsonData = JsonData.IntWrapper(data)
return j
}
if (data is String) {
j.jsonData = JsonData.StringWrapper(data)
return j
}
if (data is List<*>) {
j.jsonData = JsonData.ListWrapper(data.map {make(it)}.toMutableList())
return j
}
throw Exception("oops$data")
}Nir
07/16/2020, 7:43 PMNir
07/16/2020, 7:43 PMval list = listOf(1,2,3)
val j2 = JsonValue.make(listOf(list, list, list))Fleshgrinder
07/16/2020, 7:43 PMFleshgrinder
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:44 PMNir
07/16/2020, 7:45 PMNir
07/16/2020, 7:46 PMFleshgrinder
07/16/2020, 7:47 PMNir
07/16/2020, 7:48 PMNir
07/16/2020, 7:48 PMlistOf(ArbitraryClass())Fleshgrinder
07/16/2020, 7:48 PMAny?, only the types you actually support.Nir
07/16/2020, 7:49 PMList<Any?>Nir
07/16/2020, 7:49 PMNir
07/16/2020, 7:49 PMFleshgrinder
07/16/2020, 7:49 PMList<Any?> is good enough for JSON because JSON arrays contain arbitrary data.Nir
07/16/2020, 7:49 PMNir
07/16/2020, 7:50 PMFleshgrinder
07/16/2020, 7:50 PMAny? type. 😉Nir
07/16/2020, 7:50 PMNir
07/16/2020, 7:51 PMFleshgrinder
07/16/2020, 7:51 PMlistOf(ArbitraryClass()) is covered by List<Any?>Fleshgrinder
07/16/2020, 7:51 PMAny? type are you thinking of?Nir
07/16/2020, 7:51 PMNir
07/16/2020, 7:51 PMNir
07/16/2020, 7:51 PMNir
07/16/2020, 7:52 PMList<Int>, List<String>, List<List<String>>, etcFleshgrinder
07/16/2020, 7:52 PMNir
07/16/2020, 7:52 PMList<SomeClass>Nir
07/16/2020, 7:52 PMFleshgrinder
07/16/2020, 7:52 PMNir
07/16/2020, 7:53 PMNir
07/16/2020, 7:54 PMNir
07/16/2020, 7:54 PMNir
07/16/2020, 7:55 PMNir
07/16/2020, 7:55 PMFleshgrinder
07/16/2020, 7:56 PMNir
07/16/2020, 7:58 PMNir
07/16/2020, 8:00 PMNir
07/16/2020, 8:00 PMFleshgrinder
07/16/2020, 8:02 PMNir
07/16/2020, 8:04 PMFleshgrinder
07/16/2020, 8:04 PMFleshgrinder
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMJsonData sealed class works pretty wellNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:05 PMNir
07/16/2020, 8:07 PMfun maybeGet(index: Int): Dynamic? =Nir
07/16/2020, 8:07 PMNir
07/16/2020, 8:07 PMNir
07/16/2020, 8:07 PMFleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMclass JsonValue {
...
fun maybeGet(index: Int): JsonValue?
}Fleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMNir
07/16/2020, 8:08 PMFleshgrinder
07/16/2020, 8:08 PMNir
07/16/2020, 8:09 PMFleshgrinder
07/16/2020, 8:09 PMAny? is valid JSON.Nir
07/16/2020, 8:09 PMNir
07/16/2020, 8:09 PMNir
07/16/2020, 8:09 PMmaybeGet should return that class (nullable)Nir
07/16/2020, 8:10 PMNir
07/16/2020, 8:10 PMNir
07/16/2020, 8:10 PMFleshgrinder
07/16/2020, 8:10 PMNir
07/16/2020, 8:11 PMdynamic keywordFleshgrinder
07/16/2020, 8:11 PMNir
07/16/2020, 8:11 PMFleshgrinder
07/16/2020, 8:11 PMsomeJsonList.maybeGet(0)?.unwrap<String>()Nir
07/16/2020, 8:11 PMNir
07/16/2020, 8:12 PMFleshgrinder
07/16/2020, 8:12 PMgetOrNull would be more idiomatic Kotlin, this class is a little older than that convention.Nir
07/16/2020, 8:12 PMNir
07/16/2020, 8:12 PMNir
07/16/2020, 8:12 PM.unwrap is another great example thoughNir
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PMFleshgrinder
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PM.unwrap<SomeUserType>() that should really be a compilation errorFleshgrinder
07/16/2020, 8:13 PMNir
07/16/2020, 8:13 PMNir
07/16/2020, 8:14 PMNir
07/16/2020, 8:14 PMFleshgrinder
07/16/2020, 8:14 PMSomeUserType without knowing about your JSON document and actually understanding if that JSON value can be deserialized to your SomeUserType?!?Fleshgrinder
07/16/2020, 8:14 PMNir
07/16/2020, 8:15 PMx: Union[Int, String] and reject something like x.unwrap<List<Int>>() }Nir
07/16/2020, 8:15 PMFleshgrinder
07/16/2020, 8:15 PMx can only be of Int or String but that doesn't say anything about a random JSON value you retrieved at runtime.Nir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMNir
07/16/2020, 8:16 PMFleshgrinder
07/16/2020, 8:16 PMAny? because we don't know if {"foo":"bar"} can be deserialized to SomeUserType and/or SomeOtherUserType at compile time.Nir
07/16/2020, 8:16 PMNir
07/16/2020, 8:17 PMFleshgrinder
07/16/2020, 8:19 PMunwrap. 🙂Fleshgrinder
07/16/2020, 8:20 PMasString, asInt, as... functions.Fleshgrinder
07/16/2020, 8:20 PMList and Map cases are covered with the asList and asMap functions.Nir
07/16/2020, 8:21 PMNir
07/16/2020, 8:21 PMFleshgrinder
07/16/2020, 8:21 PMasList returns List<Dynamic> and you need to decide once more what it is.Nir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMList<List<int>> immediatelyNir
07/16/2020, 8:22 PMNir
07/16/2020, 8:22 PMFleshgrinder
07/16/2020, 8:22 PMDynamic class.Nir
07/16/2020, 8:23 PMNir
07/16/2020, 8:23 PMNir
07/16/2020, 8:23 PMauto j = json::parse(....)
vector<vector<double>> = j;Nir
07/16/2020, 8:23 PMNir
07/16/2020, 8:24 PMstruct foo{};
vector<vector<foo>> = j;Nir
07/16/2020, 8:24 PMFleshgrinder
07/16/2020, 8:29 PMNir
07/16/2020, 8:39 PMNir
07/16/2020, 8:39 PMNir
07/16/2020, 8:39 PMFleshgrinder
07/16/2020, 9:05 PMauto j = json::parse(....)
vector<vector<double>> = j;
This can never give you a compile time error because the compiler doesn't know what ... is. If it's "{}" it's not a vector<vector<double>>. What the compiler may know is that both vector and double are possible values for the return (incl. nesting) but not if the parse result is actually a vector<vector<double>>.Fleshgrinder
07/16/2020, 9:06 PMtypealias JsonValue = Boolean | List<JsonValue> | Map<String, JsonValue> | Number | String (although Long is actually not entirely representable in JSON but that's another story).Nir
07/16/2020, 9:08 PMNir
07/16/2020, 9:08 PMNir
07/16/2020, 9:08 PMvector<vector<Foo>> = j; is a compile time errorFleshgrinder
07/16/2020, 9:08 PMNir
07/16/2020, 9:09 PMNir
07/16/2020, 9:09 PMNir
07/16/2020, 9:10 PMNir
07/16/2020, 9:11 PMFleshgrinder
07/16/2020, 9:32 PMMatteo Mirk
07/18/2020, 11:01 AM