Raphtory icon indicating copy to clipboard operation
Raphtory copied to clipboard

Create a macro to reduce the boilterplate to expose an algorithm in graphql

Open ricopinazo opened this issue 2 years ago • 0 comments

RIght now we need to do something along these lines:

impl Algo for Pagerank {
    fn output_type() -> TypeRef {
        // first _nn means that the list is never nul, second _nn means no element is null
        TypeRef::named_nn_list_nn(Self::get_type_name()) //
    }
    fn args<'a>() -> Vec<(&'a str, TypeRef)> {
        vec![
            ("iterCount", TypeRef::named_nn(TypeRef::INT)), // _nn stands for not null
            ("threads", TypeRef::named(TypeRef::INT)),      // this one though might be null
            ("tol", TypeRef::named(TypeRef::FLOAT)),
        ]
    }
    fn apply_algo<'a, G: GraphViewOps>(
        graph: &G,
        ctx: ResolverContext,
    ) -> FieldResult<Option<FieldValue<'a>>> {
        let iter_count = ctx.args.try_get("iterCount")?.u64()? as usize;
        let threads = ctx.args.get("threads").map(|v| v.u64()).transpose()?;
        let threads = threads.map(|v| v as usize);
        let tol = ctx.args.get("tol").map(|v| v.f32()).transpose()?;
        let result = unweighted_page_rank(graph, iter_count, threads, tol)
            .into_iter()
            .map(|pair| FieldValue::owned_any(Pagerank::from(pair)));
        Ok(Some(FieldValue::list(result)))
    }
}

This is redundant, since the types for the output and the type, name and optionality for the arguments could be inferred from the signature of the function defining the algorithm. This can only be done using a rust macro though.

ricopinazo avatar May 19 '23 15:05 ricopinazo