如何根据带有rust proptest的schema创建JSON对象策略?

uqzxnwby  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(129)

我想使用rust proptest库创建一个JSON策略。但是,我不想创建一个任意的JSON。我想根据一个模式(更具体地说,OpenAPI模式)创建它。这意味着JSON的键是已知的,我不想使用任何策略创建它们,但我想使用该策略创建值(非常递归)。
我已经实现了原语类型的策略,但是我不知道如何创建JSON对象策略。
我希望策略的类型为BoxedStratedy<serde_json::Value>,或者能够将策略Map到此类型,因为JSON对象可以包含其他对象,因此我需要能够组合策略。
我发现了一个HashMapStrategy策略,但是它只能由一个hash_map函数创建,这个函数有两个策略--一个用于生成键,一个用于值。我想我可以使用Just策略来生成键,但是它没有任何结果。也许可以使用prop_filter_map
Here是代码。也有测试。一个是通过的,因为它只测试原语类型,另一个是失败的,因为我没有找到实现generate_json_object函数的方法。
我试过了,但是类型不匹配,不是从stringMap到JSON值的策略,而是从stringMap到BoxedStrategy的策略。

fn generate_json_object(object: &ObjectType) -> BoxedStrategy<serde_json::Value> {
    let mut json_object = serde_json::Map::with_capacity(object.properties.len());
    for (name, schema) in &object.properties {
        let schema_kind = &schema.to_item_ref().schema_kind;
        json_object.insert(name.clone(), schema_kind_to_json(schema_kind));
    }
    Just(serde_json::Value::Object(json_object)).boxed()
}
nnsrf1az

nnsrf1az1#

我们可以创建一个策略向量,它实现了一个Strategy特征,并且可以被装箱。我们创建一个元组向量,第一个元素是键的Just,第二个元素是值的装箱策略,值的装箱策略可以由schema_kind_to_json函数创建。在我们有了一个实现Strategy的元组向量之后,我们可以使用.prop_map将其转换为serde_json::Value::Object

fn generate_json_object(object: &ObjectType) -> BoxedStrategy<serde_json::Value> {
    let mut vec = Vec::with_capacity(object.properties.len());
    for (name, schema) in &object.properties {
        let schema_kind = &schema.to_item_ref().schema_kind;
        vec.push((Just(name.clone()), schema_kind_to_json(schema_kind)));
    }
    vec.prop_map(|vec| serde_json::Value::Object(serde_json::Map::from_iter(vec)))
        .boxed()
}

相关问题