Created
May 20, 2014 03:18
-
-
Save mausch/cde9038a160613c86072 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// see http://bugsquash.blogspot.com/2014/05/mapping-objects-to-json-with-fleece.html for some background | |
open System | |
type AccountIdentifier = AccountIdentifier of Guid | |
type Account = { | |
Identifier : AccountIdentifier | |
Name : string | |
} | |
type Guid with | |
static member tryParse (x: string) = | |
match Guid.TryParse x with | |
| true, g -> Some g | |
| _ -> None | |
open Fleece // http://www.nuget.org/packages/Fleece/ | |
open Fleece.Operators | |
open FSharpPlus | |
type AccountIdentifier with | |
static member ToJSON (AccountIdentifier x) = toJSON (x.ToString()) | |
static member FromJSON (_: AccountIdentifier) = | |
function | |
| JString x -> | |
match Guid.tryParse x with | |
| Some g -> Success (AccountIdentifier g) | |
| _ -> Failure (sprintf "Wrong AccountIdentifier: %s" x) | |
| x -> Failure (sprintf "Wrong AccountIdentifier: %A" x) | |
type Account with | |
static member ToJSON (x: Account) = | |
jobj [ | |
"identifier" .= x.Identifier | |
"name" .= x.Name | |
] | |
static member FromJSON (_: Account) = | |
function | |
| JObject o -> | |
monad { | |
let! id = o .@ "identifier" | |
let! name = o .@ "name" | |
return { | |
Account.Identifier = id | |
Name = name | |
} | |
} | |
| x -> Failure (sprintf "Wrong Account: %A" x) | |
[<EntryPoint>] | |
let main _ = | |
let id = System.Guid.NewGuid() |> AccountIdentifier | |
let account = {Identifier = id; Name = "Accounts Receiveable"} | |
let d = [ id, account ] |> Map.ofList | |
let stringVersion = d :> _ seq |> Seq.map (fun (KeyValue(AccountIdentifier k, v)) -> k.ToString(), v) |> Map.ofSeq |> toJSON |> fun x -> x.ToString() | |
printfn "%s" stringVersion | |
let asMapStringAccount = | |
monad { | |
let! mapStringAccount = parseJSON stringVersion : Map<string, Account> ParseResult | |
let! parsedKeysValues = | |
mapStringAccount :> _ seq | |
|> traverse (fun (KeyValue(s,v)) -> | |
match Guid.tryParse s with | |
| Some g -> Success (AccountIdentifier g, v) | |
| _ -> Failure (sprintf "Error parsing Guid %s" s)) | |
return Map.ofSeq parsedKeysValues | |
} | |
match asMapStringAccount with | |
| Failure e -> failwithf "Error parsing accounts: %s" e | |
| Success roundTripResult -> printfn "%s" roundTripResult.[id].Name | |
0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment