Skip to content

Instantly share code, notes, and snippets.

@mausch
Created May 20, 2014 03:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mausch/cde9038a160613c86072 to your computer and use it in GitHub Desktop.
Save mausch/cde9038a160613c86072 to your computer and use it in GitHub Desktop.
// 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