g1-common 0.1.0-alpha.3

Common types and traits between the client and server portion of the G1 graph store.
//! Proptest strategies for queries.

use crate::query::{Clause, Predicate, Query, Value};
use proptest::{
    arbitrary::{any, Arbitrary},
    collection::{vec, VecStrategy},
    prop_oneof,
    strategy::{LazyTupleUnion, Map, Strategy, WA},
};

const STRING_REGEX: &'static str = "[ -~]*";

impl Arbitrary for Value {
    type Parameters = ();
    type Strategy = LazyTupleUnion<(
        WA<Map<&'static str, fn(String) -> Value>>,
        WA<Map<&'static str, fn(String) -> Value>>,
    )>;

    fn arbitrary_with((): ()) -> Self::Strategy {
        prop_oneof![
            STRING_REGEX.prop_map(Value::Str),
            STRING_REGEX.prop_map(Value::Var),
        ]
    }
}

impl Arbitrary for Predicate {
    type Parameters = ();
    type Strategy = Map<
        (&'static str, VecStrategy<<Value as Arbitrary>::Strategy>),
        fn((String, Vec<Value>)) -> Predicate,
    >;

    fn arbitrary_with((): ()) -> Self::Strategy {
        (STRING_REGEX, vec(any::<Value>(), 0..5)).prop_map(|(name, args)| Predicate { name, args })
    }
}

impl Arbitrary for Clause {
    type Parameters = ();
    type Strategy = Map<
        (
            <Predicate as Arbitrary>::Strategy,
            VecStrategy<(
                <bool as Arbitrary>::Strategy,
                <Predicate as Arbitrary>::Strategy,
            )>,
        ),
        fn((Predicate, Vec<(bool, Predicate)>)) -> Clause,
    >;

    fn arbitrary_with((): ()) -> Self::Strategy {
        (any::<Predicate>(), vec(any::<(bool, Predicate)>(), 0..8))
            .prop_map(|(head, body)| Clause { head, body })
    }
}

impl Arbitrary for Query {
    type Parameters = ();
    type Strategy = Map<
        (
            VecStrategy<<Clause as Arbitrary>::Strategy>,
            <Predicate as Arbitrary>::Strategy,
        ),
        fn((Vec<Clause>, Predicate)) -> Query,
    >;

    fn arbitrary_with((): ()) -> Self::Strategy {
        (vec(any::<Clause>(), 0..10), any::<Predicate>())
            .prop_map(|(clauses, goal)| Query { clauses, goal })
    }
}