Yocto (empty) → 0.1.0
raw patch · 4 files changed
+118/−0 lines, 4 filesdep +basedep +containersdep +parsecsetup-changed
Dependencies added: base, containers, parsec
Files
- LICENSE +20/−0
- Setup.hs +2/−0
- Text/JSON/Yocto.hs +76/−0
- Yocto.cabal +20/−0
+ LICENSE view
@@ -0,0 +1,20 @@+The MIT License (MIT)++Copyright (c) 2014 Alvaro J. Genial++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of+the Software, and to permit persons to whom the Software is furnished to do so,+subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Text/JSON/Yocto.hs view
@@ -0,0 +1,76 @@+-- Copyright 2014 Alvaro J. Genial [http://alva.ro]; see LICENSE file for more.+module Text.JSON.Yocto (Value (..)) where++import Control.Applicative hiding ((<|>), many)+import Data.Char (isControl)+import Data.List (intercalate)+import Data.Map (fromList, Map, toList)+import Data.Ratio ((%), denominator, numerator)+import Prelude hiding (exp, exponent, null)+import Numeric (fromRat, readDec, readHex, showHex)+import Text.Parsec hiding (string, token)+import qualified Text.Parsec as Parsec++data Value = Null+ | Boolean Bool+ | Number Rational+ | String String+ | Array [Value]+ | Object (Map String Value)+ deriving (Eq, Ord)++instance Show Value where+ show Null = "null"+ show (Boolean b) = if b then "true" else "false"+ show (Number n) = show $ fromRat n+ show (String s) = "\"" ++ concat (escape <$> s) ++ "\""+ show (Array a) = "[" ++ intercalate "," (show <$> a) ++ "]"+ show (Object o) = "{" ++ intercalate "," (f <$> toList o) ++ "}"+ where f (n, v) = show n ++ ":" ++ show v++escape c = maybe control (\e -> '\\' : [e]) (c `lookup` exceptions) where+ control = if isControl c then (encode . showHex . fromEnum) c else [c]+ encode hex = "\\u" ++ replicate (4 - length s) '0' ++ s where s = hex ""+ exceptions = [('\b', 'b'), ('\f', 'f'), ('\n', 'n'), ('\r', 'r'),+ ('\t', 't'), ('\\', '\\'), ('"', '"')]++instance Read Value where+ readsPrec _ string = attempt $ parse input "JSON" string+ where attempt (Left failure) = error $ "invalid " ++ show failure+ attempt (Right success) = [success]++input = (whitespace >> value) & getInput where+ value = null <|> string <|> array <|> object <|> number <|> boolean++ null = Null <$ keyword "null"+ boolean = Boolean <$> (True <$ keyword "true" <|> False <$ keyword "false")+ number = Number <$> rational <$> lexical (integer & fraction & exponent)+ string = String <$> many character `within` (char, '"', '"')+ array = Array <$> commaSep value `within` (token, '[', ']')+ object = Object <$> fromList <$> commaSep pair `within` (token, '{', '}')++ pair = name & (token ':' >> value) where name = (\(String s) -> s) <$> string+ character = satisfy (not . \c -> isControl c || elem c "\"\\") <|> escape+ where escape = char '\\' >> (oneOf "\"\\/bfnrt" <|> unicode)+ unicode = char 'u' >> ordinal <$> count 4 hexDigit++ integer = fromInteger <$> (0 <$ char '0' <|> natural) `maybeSignedWith` minus+ fraction = option 0 (char '.' >> fmap fractional (many1 digit))+ exponent = option 0 (oneOf "eE" >> natural `maybeSignedWith` (plus <|> minus))++ a & b = (,) <$> a <*> b+ token = lexical . Parsec.char+ keyword = lexical . Parsec.string+ commaSep = (`sepBy` token ',')+ whitespace = many (oneOf " \t\r\n")++ items `within` (term, start, end) = term start *> items <* term end+ number `maybeSignedWith` sign = ($ 0) <$> option (+) sign <*> number+ (plus, minus) = ((+) <$ char '+', (-) <$ char '-')++ lexical = (<* whitespace)+ integral = fst . head . readDec+ ordinal = toEnum . fst . head . readHex+ natural = integral <$> many1 digit+ fractional digits = integral digits % (10 ^ length digits)+ rational ((int, frac), exp) = (int + (signum int * frac)) * 10 ^^ exp
+ Yocto.cabal view
@@ -0,0 +1,20 @@+Name: Yocto+Version: 0.1.0+Author: Alvaro J. Genial+Maintainer: ajg+Homepage: https://github.com/ajg/yocto+Synopsis: A Minimal JSON Parser & Printer for Haskell+Description: Hassle-free, fast, lossless encoding & decoding of JSON.+License: MIT+License-File: LICENSE+Category: Text+Build-type: Simple+Cabal-version: >= 1.6++Library+ Exposed-modules: Text.JSON.Yocto+ Build-depends: base >= 4 && < 5, containers >= 0.1, parsec >= 3++source-repository head+ type: git+ location: https://github.com/ajg/yocto/tree/master