如何在编译时确保类型将序列化为JSON数组?

时间:2018-09-28 20:52:30

标签: rust serde

我有一个特征,可以用作Rails ActiveJob的接口;我希望我的Rust后端触发工作由Rails API处理:

trait BackgroundJob {
    type Args: Serialize;
    const QUEUE: &'static str;
    const CLASS: JobClass;

    fn payload(self) -> Self::Args;
}

特征的示例实现:

impl BackgroundJob for MyJob {
    type Args = (String,);
    const QUEUE: &'static str = "my_queue";
    const CLASS: JobClass = JobClass::Job1;

    fn payload(self) -> Self::Args {
        (self.payload,)
    }
}

playground

在我的应用程序中,代码稍微复杂一些(具体来说,我有一个Actix actor而不是BackgroundJob上的泛型函数),但是思想是相同的。

此代码可以正常工作,但是我必须确保BackgroundJob的所有实现都将某些东西序列化为JSON数组(以与活动作业一起使用)作为Args类型参数。

我想做的是保证编译时Args将序列化为数组。有可能吗?

我尝试解决Serde的SerializeTupleSerializeSeq特征,但没有成功。

1 个答案:

答案 0 :(得分:1)

我很确定答案是“不,Serde没有做到这一点的本机”。没有与此特定需求相对应的特征。

您可以创建自己的标记特征并要求它存在,但是不会自动被任何东西实现;您必须为任何有效类型手动实现它。我猜那不是您想要的东西:

trait SerializeToJsonArray {}

impl<T> SerializeToJsonArray for Vec<T> {}
impl<T> SerializeToJsonArray for [T] {}
impl<A> SerializeToJsonArray for (A, ) {}
impl<A, B> SerializeToJsonArray for (A, B, ) {}
impl<A, B, C> SerializeToJsonArray for (A, B, C, ) {}
// etc.

trait BackgroundJob {
    type Args: Serialize + SerializeToJsonArray;
}

这也是很容易破解的-您可以轻松实现{strong>不序列化为数组的类型的SerializeToJsonArray。同样,Serde不了解此特征,您仍然需要在序列化时处理非数组。