yamlkeysdiff-0.5.1: src/YamlKeysDiff/Diff.hs
-- Copyright (c) 2015 Antoine Catton
--
-- This file is part of YAMLKeysDiff and is distributed under EUPLv1.1,
-- see the LICENSE file for more information. If a LICENSE file wasn't
-- provided with this piece of software, you will find a copy at:
-- <http://ec.europa.eu/idabc/eupl.html>
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-- THE SOFTWARE.
module YamlKeysDiff.Diff where
import qualified Data.HashMap.Lazy as HashMap
import Data.Maybe (fromMaybe)
import qualified Data.List as List
import Data.Text (unpack)
import Data.Yaml (Value(Object))
data DiffLine = DiffMissing [String]
| DiffAdded [String]
| DiffSimilar [String]
isSimilar :: DiffLine -> Bool
isSimilar (DiffSimilar key) = True
isSimilar _ = False
getKeys :: Value -> [[String]]
getKeys value =
let getObject (Object obj) = Just obj
getObject _ = Nothing
go path obj = concat $ map (go' path) $ HashMap.toList obj
go' path (key, value) =
let path' = path ++ [key] in
fromMaybe [path'] $ fmap (go path') $ getObject value
in map (map unpack) $ fromMaybe [] $ fmap (go []) $ getObject value
diff :: Value -> Value -> [DiffLine]
diff contentA contentB =
let keysA = List.sort $ getKeys contentA
keysB = List.sort $ getKeys contentB
go al@(a:at) bl@(b:bt) =
if a == b then (DiffSimilar a) : go at bt
else if a < b then (DiffAdded a) : (go at bl)
else (DiffMissing b) : (go al bt)
go [] (b:t) = (DiffMissing b) : (go [] t)
go (a:t) [] = (DiffAdded a) : (go t [])
go [] [] = []
in go keysA keysB