schemars icon indicating copy to clipboard operation
schemars copied to clipboard

Deriving for remote type contains nested custom types

Open ScottLinnn opened this issue 3 years ago • 2 comments

I want to derive JsonSchema for Graph, here is the definition of Graph:

pub struct Graph<N, E, Ty = Directed, Ix = DefaultIx> {
    nodes: Vec<Node<N, Ix>>,
    edges: Vec<Edge<E, Ix>>,
    ty: PhantomData<Ty>,
}

Here, the Node, Edge, PhantomData, DefaultIx, Directed are all custom types/enums in that crate. According to the doc, it seems I need to not only copy the definition of Graph, but also all these types/enums and give them annotations. I'm wondering is there a way to do this cleaner?

Thank you!

ScottLinnn avatar May 20 '22 21:05 ScottLinnn

There isn't a tremendously clean way to do this. Here are some options:

Copy, Derive, with

You can copy the type definitions, add derive, and then do something like:

#[derive(JsonSchema)]
struct MyDataType {
    #[schemars(with = "MyGraphCopy")]
    graph: Graph<...>,
}

Here you're just using the copied type to generate the JsonSchema impl.

Hand-rolled Schema, with_schema

You could instead make a function to hang-generate the Schema:

fn graph_schema(&mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
    todo!()
}

#[derive(JsonSchema)]
struct MyDataType {
    #[schemars(with_schema = "graph_schema")]
    graph: Graph<...>,
}

Try schemars::schema_for_value()

I've never used this, but you might be able to construct a Graph instance (and use the serde feature flag for petgraph) in order to use schemars::schema_for_value() to generate a viable Schema object. This might be easier than a bunch of copy-pasting or hand-rolling a schema... if it works.

ahl avatar May 20 '22 22:05 ahl

Thank you for the answers! I'll try them out!

ScottLinnn avatar May 21 '22 01:05 ScottLinnn