fsprojects / Fleece

Json mapper for F#
http://fsprojects.github.io/Fleece
Apache License 2.0
199 stars 31 forks source link

Question : How to parse a JSON string #16

Closed MangelMaxime closed 8 years ago

MangelMaxime commented 8 years ago

Hi @mausch,

I just discovered Fleece and really appreciate it. My problem is I have a File so a string representation of Json and I would like to instantiate a type from it.

Here is the code:


type ConfigJson = {
    RelativeRoot: string
}

type ConfigJson with 
    static member Create relativeRoot = { ConfigJson.RelativeRoot = relativeRoot }

    static member FromJson(_:ConfigJson) = 
        function
        | JObject o -> ConfigJson.Create <!> (o .@ "relativeRoot")
        | x -> Failure (sprintf "Expected ConfigJson, found %A" x)

type Config private () =
    let mutable RelativeRoot = ""

    let mutable json = nullArg

    do
        let data = parseJSON(System.IO.File.ReadAllText("server.json"))
        (*ConfigJson.FromJson(data)*)(* Here is the problem *)
        |> ignore

    static let instance = Config()

I was supposing that FromJson was a method to instantiate the Type but I can't find how to use it. Sure it doesn't take a string as a entry. Could you help me please.

PS: Sorry, if the question is a little dumb.

mausch commented 8 years ago

Hi! No question is dumb.

parseJSON does take a string as parameter, but it returns a Choice<'a, string>. If it's Choice1Of2 then the parsing was successful and you have the parsed value. If it's Choice2Of2 then there was some parsing error and you get the error message as a string, which you can use to throw as an exception, display to the user or whatever you like.

Does that make sense?

To create a "singleton" instance of Config I recommend using F#'s lazy expressions

Cheers

MangelMaxime commented 8 years ago

Thanks for the answer and the tips.

I think I understand an then if the result is successful then I can pass it to FromJson of ConfigJson ?

mausch commented 8 years ago

No, FromJson is called implicitly by parseJSON, you don't need to call it in your code. On 31 May 2016 13:35, "Maxime Mangel" notifications@github.com wrote:

Thanks for the answer and the tips.

I think I understand an then if the result is successful then I can pass it to FromJson of ConfigJson ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/mausch/Fleece/issues/16#issuecomment-222675099, or mute the thread https://github.com/notifications/unsubscribe/AAFz2jjEDAcEpHnz4cBGJrefwO0sH8yTks5qHCrzgaJpZM4IqcXv .

MangelMaxime commented 8 years ago

Ok :) Thanks for the help.

I am letting here my problem solved.

namespace Server

open System
open Fleece
open Fleece.Operators
open FSharpPlus

type ConfigJson = {
    RelativeRoot: string
    Server: string
    Database: string
    Uid: string
    Pwd: string
}

type ConfigJson with 
    static member Create relativeRoot server database uid pwd= 
        { 
            ConfigJson.RelativeRoot = relativeRoot;
            ConfigJson.Server = server;
            ConfigJson.Database = database;
            ConfigJson.Uid = uid;
            ConfigJson.Pwd = pwd;
        }

    static member FromJSON (_:ConfigJson) = 
        function
        | JObject o -> ConfigJson.Create <!> (o .@ "relativeRoot") <*> (o .@ "server") <*> (o .@ "database") <*> (o .@ "uid") <*> (o .@ "pwd")
        | x -> Failure (sprintf "Expected ConfigJson, found %A" x)

module Config =

    let config: ConfigJson =
        let data: ConfigJson ParseResult = parseJSON(System.IO.File.ReadAllText("server.json"))

        match data with
        | Success a -> a
        | Failure e -> failwith "Error when parsing json file"