Question

I am trying to add a basic JSON type provider to fsharpx. At the moment I am struggeling with JSON Arrays. Consider the following test case:

type SimpleArray = JSON< "{\"items\":[{\"id\":\"Open\"},{\"id\":\"Pause\"}]}">

let a = SimpleArray()

[<Test>] 
let ``Can parse simple arrays``() = 
    a.items.[0].id
    |> should equal "Open"

    a.items.[1].id
    |> should equal "Pause"

The idea is that I want to use the first element in the array to get the type of the collection elements. Then I want to add a property "items" to the SimpleArray type that gives a list of this new type.

The code can be found in the github repo Github. The interesting part starts at line 38. As you can see the whole thing has to be recursive since the JArray could also contain nested JArrays.

| JArray list ->
    let newType = annotateAsJson list.[0] (runtimeType<obj> (ownerTy.Name + "_" + e.Key))
    ownerTy.AddMember newType
    Some(provideProperty
            e.Key
            newType // TODO: make this a list
            (fun args -> Expr.Coerce(<@@ (%%args.[0] : obj) @@>, newType)) // TODO: return the list
            :> MemberInfo)

Thanks, Steffen

Was it helpful?

Solution

What's the question, exactly? It looks like you need to provide multiple types (e.g. in your example you've got the outer type containing items and then an inner type containing id). You probably want the inner type to be a nested type within the outer type. Then you make the provided items property contain a list of the inner type. Is there a particular aspect of that which you are having trouble with?

EDIT

If it's just that you are wondering how to create the Type instance itself, have you tried

typedefof<_ list>.MakeGenericType(newType)

This presumes that the underlying value it itself an obj list, which is necessary since newType erases to obj.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top