Created
March 21, 2018 14:27
-
-
Save pirrmann/6fc518708c6cfb388b3c81280d5ab9a2 to your computer and use it in GitHub Desktop.
Differ
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
type DifferenceType<'TKey, 'T> = | |
| Added of 'TKey * 'T | |
| Removed of 'TKey * 'T | |
| Modified of 'TKey * 'T * 'T * seq<string * (string * string)> with | |
member this.Key = | |
match this with | |
| Added (key, _) | |
| Removed (key, _) | |
| Modified (key, _, _, _) -> key | |
type Differences<'TKey, 'T> = | |
{ | |
Added: ('TKey * 'T) seq | |
Removed: ('TKey * 'T) seq | |
Modified: ('TKey * 'T * 'T * seq<string * (string * string)>) seq } with | |
member this.AsSingleSeq() = seq { | |
yield! this.Added |> Seq.map Added | |
yield! this.Removed |> Seq.map Removed | |
yield! this.Modified |> Seq.map Modified | |
} | |
let getStringMapDifferences<'TKey when 'TKey:comparison> (lineBefore:Map<'TKey, string>) (lineAfter: Map<'TKey, string>) = | |
lineBefore | |
|> Map.toSeq | |
|> Seq.map (fun (key, vBefore) -> let vAfter = lineAfter.[key] in key, (vBefore, vAfter)) | |
|> Seq.filter (fun (_, (vBefore, vAfter)) -> vBefore <> vAfter) | |
let formatDifferenceChanges changes = | |
changes | |
|> Seq.map (fun (propertyName, (oldValue, newValue)) -> sprintf "%s: %s => %s" propertyName oldValue newValue) | |
|> String.concat System.Environment.NewLine | |
let getDifferences keyValueMapper itemsDiffGetter itemsBefore itemsAfter = | |
let setBefore = itemsBefore |> Set.ofSeq | |
let setAfter = itemsAfter |> Set.ofSeq | |
let itemsFoundBeforeNotFoundAfter = setBefore - setAfter | |
let itemsFoundAfterNotFoundBefore = setAfter - setBefore | |
let dicBefore = itemsFoundBeforeNotFoundAfter |> Seq.map keyValueMapper |> Map.ofSeq | |
let dicAfter = itemsFoundAfterNotFoundBefore |> Seq.map keyValueMapper |> Map.ofSeq | |
let keysBefore = dicBefore |> Map.toSeq |> Seq.map fst |> Set.ofSeq | |
let keysAfter = dicAfter |> Map.toSeq |> Seq.map fst |> Set.ofSeq | |
let removedKeys = keysBefore - keysAfter | |
let addedKeys = keysAfter - keysBefore | |
let modifiedItemsKeys = Set.intersect keysAfter keysBefore | |
{ | |
Added = | |
seq { | |
for key in addedKeys do | |
let addedItem = Map.find key dicAfter | |
yield key, addedItem | |
} | |
Removed = | |
seq { | |
for key in removedKeys do | |
let removedItem = Map.find key dicBefore | |
yield key, removedItem | |
} | |
Modified = | |
seq { | |
for key in modifiedItemsKeys do | |
let itemBefore = Map.find key dicBefore | |
let itemAfter = Map.find key dicAfter | |
yield key, itemBefore, itemAfter, itemsDiffGetter itemBefore itemAfter | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much for your gist! 👍