packages feed

bunz 0.0.5 → 0.0.6

raw patch · 2 files changed

+75/−40 lines, 2 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Beautifier: firstString :: Text -> Text
+ Beautifier: firstString :: Builder -> Builder
- Beautifier: indent :: IndentationLevel -> Text -> Text
+ Beautifier: indent :: IndentationLevel -> Builder -> Builder
- Beautifier: splitAtHead :: Text -> (Text, Text)
+ Beautifier: splitAtHead :: Builder -> (Builder, Builder)

Files

bunz.cabal view
@@ -1,5 +1,5 @@ name:                bunz-version:             0.0.5+version:             0.0.6 synopsis:            CLI tool to beautify JSON string. description:         CLI tool to beautify JSON string. homepage:            https://github.com/sendyhalim/bunz@@ -42,7 +42,7 @@                      , bunz                      , doctest >= 0.11                      , hspec == 2.4.4-  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N -O2   default-language:    Haskell2010  source-repository head
src/Beautifier.hs view
@@ -8,9 +8,10 @@   , splitAtHead   ) where -import           Data.Int       (Int64)-import           Data.Monoid    ((<>))-import qualified Data.Text.Lazy as T+import           Data.Int               (Int64)+import           Data.Monoid            ((<>))+import qualified Data.Text.Lazy         as T+import qualified Data.Text.Lazy.Builder as B  -- Doctest setup -- $setup@@ -18,18 +19,49 @@  type IndentationLevel = Int64 -indentation :: T.Text-indentation = "  " -newline :: T.Text-newline = "\n"+-- | Lift function that works with Data.Text.Lazy+-- to be able to work with Data.Text.Lazy.Builder.+-- There should be a better and faster way to manipulate builder. We're using+-- this for now because it's a lot faster than just using plain Data.Text.Lazy when+-- concatenating text.+liftToBuilder :: (T.Text -> T.Text) -> (B.Builder -> B.Builder)+liftToBuilder f = B.fromLazyText . f . B.toLazyText -indent :: IndentationLevel -> T.Text -> T.Text-indent level str = T.replicate level indentation <> str+splitAt' :: Int64 -> B.Builder -> (B.Builder, B.Builder)+splitAt' n str = (B.fromLazyText head, B.fromLazyText tail)+  where (head, tail) = T.splitAt n (B.toLazyText str) -trimmedTail :: T.Text -> T.Text-trimmedTail = T.stripStart . T.tail+head' :: B.Builder -> B.Builder+head' = B.singleton . T.head . B.toLazyText +tail' :: B.Builder -> B.Builder+tail' = liftToBuilder T.tail++drop' :: Int64 -> B.Builder -> B.Builder+drop' length = liftToBuilder (T.drop length)++length' :: B.Builder -> Int64+length' = T.length . B.toLazyText++stripStart' :: B.Builder -> B.Builder+stripStart' =  liftToBuilder T.stripStart++space :: T.Text+space = " "++indentation :: IndentationLevel -> B.Builder+indentation level = B.fromLazyText (T.replicate level space)++newline :: B.Builder+newline = B.fromLazyText "\n"++indent :: IndentationLevel -> B.Builder -> B.Builder+indent level str = indentation level <> str++trimmedTail :: B.Builder -> B.Builder+trimmedTail = B.fromLazyText . T.stripStart . T.tail . B.toLazyText+ -- | Split the given string at its head while honouring escaped string. -- Examples: --@@ -38,10 +70,10 @@ -- -- >>> splitAtHead "\nyeay" -- ("\n","yeay")-splitAtHead :: T.Text -> (T.Text, T.Text)+splitAtHead :: B.Builder -> (B.Builder, B.Builder) splitAtHead "" = ("", "")-splitAtHead str@(T.head -> '\\') = T.splitAt 2 str-splitAtHead str = T.splitAt 1 str+splitAtHead str@(head' -> "\\") = splitAt' 2 str+splitAtHead str = splitAt' 1 str  -- | Extract string within double quotes `"` including the double quotes ignoring -- the suffix after closing quote `"`@@ -50,13 +82,13 @@ -- -- >>> string False "\"test\"whatuppp" -- "\"test\""-string :: Bool -> T.Text -> T.Text-string False str@(T.head -> '"') = "\"" <> string True (T.tail str)-string True str@(T.head -> '"') = "\""+string :: Bool -> B.Builder -> B.Builder+string False str@(head' -> "\"") = "\"" <> string True (tail' str)+string True str@(head' -> "\"") = "\"" string True str = let (head, tail) = splitAtHead str in head <> string True tail  -- | Extract the first string value starting from the front.-firstString :: T.Text -> T.Text+firstString :: B.Builder -> B.Builder firstString str = string False str  @@ -85,30 +117,33 @@ -- -- >>> extractJsonValue "false,true,false]" -- "false"-extractJsonValue :: T.Text -> T.Text-extractJsonValue = T.takeWhile (not . isEndOfValue)+extractJsonValue :: B.Builder -> B.Builder+extractJsonValue = liftToBuilder $ T.takeWhile (not . isEndOfValue)  -- |Beautify the given JSON text based on the current indentation level.-beautifyText :: IndentationLevel -> T.Text -> T.Text+beautifyText :: IndentationLevel -> B.Builder -> B.Builder beautifyText i str   | str == "" = ""-  | head == ' ' = stripStartThenParse str-  | head == '\n' = stripStartThenParse str-  | head == '\t' = stripStartThenParse str-  | head == '{' = nextLineAfterOpening "{"-  | head == '[' = nextLineAfterOpening "["-  | head == '}' = nextLineAfterClosing "}"-  | head == ']' = nextLineAfterClosing "]"-  | head == ',' = "," <> newline <> indent i (beautifyText i (trimmedTail str))-  | head == '"' = let groupedString = firstString str-                      restOfTheString = T.drop (T.length groupedString) str-                  in groupedString <> beautifyText i restOfTheString-  | head == ':' = ": " <> beautifyText i (trimmedTail str)-  | otherwise = let value = extractJsonValue str-                in value <> beautifyText i (T.drop (T.length value) str)+  | head == " " = stripStartThenParse str+  | head == "\n" = stripStartThenParse str+  | head == "\t" = stripStartThenParse str+  | head == "{" = nextLineAfterOpening "{"+  | head == "[" = nextLineAfterOpening "["+  | head == "}" = nextLineAfterClosing "}"+  | head == "]" = nextLineAfterClosing "]"+  | head == "," = "," <> newline <> indent i (beautifyText i (trimmedTail str))+  | head == "\"" =+      let groupedString = firstString str+          restOfTheString = drop' (length' groupedString) str+          in groupedString <> beautifyText i restOfTheString+  | head == ":" = ": " <> beautifyText i (trimmedTail str)+  | otherwise =+      let value = extractJsonValue str+          valueLength = length' value+          in value <> beautifyText i (drop' valueLength str)   where-    head = T.head str-    stripStartThenParse = beautifyText i . T.stripStart+    head = head' str+    stripStartThenParse = beautifyText i . stripStart'     nextLineAfterOpening token = token       <> newline       <> indent (i + 1) (beautifyText (i + 1) (trimmedTail str))@@ -118,4 +153,4 @@   beautify :: T.Text -> T.Text-beautify = beautifyText 0+beautify = B.toLazyText . beautifyText 0 . B.fromLazyText