我需要将数据从Rust传递到Android(Kotlin) &iOS(迅速)。我可以控制所有的管道。
我的问题是,不同的表示改变了多少努力在编码移动端,什么是"容易/默认";其中一方使另一方需要填充手动解码/编码样板(这是我希望避免的!)。
这是不可伸缩的,因为我将有几十个潜在的结构体跨3种语言。
我的理想是写得不复杂:
#[derive(Debug, Deserialize, Serialize)]
pub enum Request {
Menu { company: String },
}
enum Request: Codable {
case Menu(company:String)
}
@Serializable
sealed class Request {
@Serializable
class Menu(val company: String) : Request()
}
这主要是关于枚举的。在json中存在许多表示枚举的方法:
https://serde.rs/enum-representations.html
#[derive(Serialize, Deserialize)]
enum Message {
Request { id: String, method: String, params: Params },
Response { id: String, result: Value },
}
外部标记{"Request": {"id": "...", "method": "...", "params": {...}}}
内部标记
{"type": "Request", "id": "...", "method": "...", "params": {...}}
相邻标记
{"t": "Para", "c": [{...}, {...}]}
{"t": "Str", "c": "the string"}
未加标签的
{"id": "...", "method": "...", "params": {...}}
Kotlin序列化看起来默认是"但是Swift是"外部标记"的。
那么,如何统一一切呢?
我通过在Rust上切换条件编译来解决这个问题,以匹配移动端的默认值:
#[cfg(not(target_os = "android"))]
#[derive(Debug, Deserialize, Serialize)]
pub enum Response {
Menu { modules: Vec<Menu> },
Fail(JsonError),
}
#[cfg(target_os = "android")]
#[derive(Debug, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum Response {
Menu { modules: Vec<Menu> },
Fail(JsonError),
}