packages feed

hosc-json 0.14 → 0.15

raw patch · 5 files changed

+110/−28 lines, 5 filesdep ~aesondep ~hoscPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: aeson, hosc

API changes (from Hackage documentation)

- Sound.OSC.Type.JSON.Aeson: encode_floating :: (Real n, Floating n) => n -> Value
- Sound.OSC.Type.JSON.Aeson: encode_integral :: Integral n => n -> Value
+ Sound.OSC.Type.JSON: encode_floating :: (Real n, Floating n) => n -> Value
+ Sound.OSC.Type.JSON: encode_integral :: Integral n => n -> Value
+ Sound.OSC.Type.JSON.Aeson: decode_double :: Value -> Maybe Double
+ Sound.OSC.Type.JSON.Aeson: decode_double_err :: Value -> Double
+ Sound.OSC.Type.JSON.Aeson: decode_integer :: Value -> Maybe Integer
+ Sound.OSC.Type.JSON.Aeson: decode_number_err :: Value -> Either Integer Double
+ Sound.OSC.Type.JSON.Aeson: encode_double :: Double -> Value
+ Sound.OSC.Type.JSON.Aeson: encode_integer :: Integer -> Value
+ Sound.OSC.Type.JSON.Aeson: result_maybe :: Result a -> Maybe a
+ Sound.OSC.Type.JSON.Math: in_int16 :: Integral a => a -> Bool
+ Sound.OSC.Type.JSON.Math: in_int32 :: Integral a => a -> Bool
+ Sound.OSC.Type.JSON.Math: in_int64 :: Integral a => a -> Bool
+ Sound.OSC.Type.JSON.Math: in_int8 :: Integral a => a -> Bool
+ Sound.OSC.Type.JSON.Math: in_range :: (Integral r, Integral n) => r -> r -> n -> Bool
+ Sound.OSC.Type.JSON.Math: ratio_is_bounded_integral :: Integral n => n -> Ratio n -> Bool
+ Sound.OSC.Type.JSON.Math: ratio_is_int :: Integral n => Ratio n -> Bool
+ Sound.OSC.Type.JSON.Math: ratio_is_integral :: Integral n => Ratio n -> Bool
+ Sound.OSC.Type.JSON.Math: ratio_is_word8 :: Integral n => Ratio n -> Bool

Files

README view
@@ -15,9 +15,9 @@ Message "/m" [Int32 0]      ["/m",0] Bundle 0 [Message "/m" []]  ["#bundle",{"timestamp":0.0},["/m"]] -[hosc]: http://rd.slavepianos.org/?t=hosc+[hosc]: http://rd.slavepianos.org/t/hosc [json]: http://www.json.org/ -© rd, 2013, [gpl]+© [rd](http://rd.slavepianos.org), 2013-2014, [gpl]  [gpl]: http://gnu.org/copyleft/
Sound/OSC/Type/JSON.hs view
@@ -5,8 +5,9 @@ import qualified Data.ByteString.Char8 as C {- bytestring -} import qualified Data.ByteString.Lazy as B.L {- bytestring -} import qualified Data.ByteString.Lazy.UTF8 as U {- utf8-string -}+ import Sound.OSC as O {- hosc -}-import Sound.OSC.Type.JSON.Aeson {- hosc -}+import Sound.OSC.Type.JSON.Aeson {- hosc-json -}  -- * Library variant @@ -20,6 +21,10 @@ encode_json_str = U.toString . encode_json  -- | 'String' variant of 'decode_json'.+--+-- > import Sound.OSC.Type.JSON+-- > let j = decode_json_str "[\"/n_set\",-1,\"c1\",66]"+-- > fmap decode_message j decode_json_str :: String -> Maybe Value decode_json_str = decode_json . U.fromString @@ -30,12 +35,18 @@  -- | Encode 'Number'. encode_number :: Number -> Value-encode_number = either encode_integral encode_floating+encode_number = either encode_integer encode_double  -- | Encode 'O.TimeStamp' data ('O.Time'), ie. the @hosc@ real-valued -- @NRT@ representation. encode_timestamp :: Time -> Value-encode_timestamp n = encode_assoc ("timestamp",encode_floating n)+encode_timestamp n = encode_assoc ("timestamp",encode_double n)++encode_integral :: Integral n => n -> Value+encode_integral = encode_integer . fromIntegral++encode_floating :: (Real n,Floating n) => n -> Value+encode_floating = encode_double . realToFrac  -- | Encode 'O.Blob' data ('B.L.ByteString'). encode_blob :: B.L.ByteString -> Value
Sound/OSC/Type/JSON/Aeson.hs view
@@ -2,15 +2,18 @@ module Sound.OSC.Type.JSON.Aeson where  import qualified Data.Aeson as A {- aeson -}-import qualified Data.Attoparsec.Number as N {- attoparsec -} import Data.Bifunctor {- bifunctors -} import qualified Data.ByteString.Lazy as B.L {- bytestring -} import qualified Data.HashMap.Strict as M {- unordered-containers -}+import Data.Maybe {- base -} import qualified Data.Vector as V {- vector -} import Data.Word {- base -} import qualified Data.Text as T {- text -}+ import Sound.OSC.Type {- hosc -} +import Sound.OSC.Type.JSON.Math {- hosc-json -}+ -- * Library variant  -- | Encode 'A.Value' to 'B.L.ByteString'.@@ -24,12 +27,12 @@ -- * Encoders  -- | All 'Integral' values are packed to 'Integer'.-encode_integral :: Integral n => n -> A.Value-encode_integral = A.Number . N.I . fromIntegral+encode_integer :: Integer -> A.Value+encode_integer = A.toJSON  -- | All 'Floating' values are packed to 'Double'.-encode_floating :: (Real n,Floating n) => n -> A.Value-encode_floating = A.Number . N.D . realToFrac+encode_double :: Double -> A.Value+encode_double = A.toJSON  -- | Pack 'String'. encode_string :: String -> A.Value@@ -68,28 +71,51 @@             _ -> Nothing       _ -> Nothing +result_maybe :: A.Result a -> Maybe a+result_maybe r =+    case r of+      A.Success r' -> Just r'+      A.Error _ -> Nothing++decode_integer :: A.Value -> Maybe Integer+decode_integer = result_maybe . A.fromJSON++decode_double :: A.Value -> Maybe Double+decode_double = result_maybe . A.fromJSON+ -- > map decode_number [encode_integral 0,encode_floating 1] decode_number :: A.Value -> Maybe (Either Integer Double) decode_number j =-    case j of-      A.Number n -> case n of-                      N.I i -> Just (Left i)-                      N.D d -> Just (Right d)-      _ -> Nothing+    case decode_integer j of+      Just i -> Just (Left i)+      Nothing -> case decode_double j of+                   Just d -> Just (Right d)+                   Nothing -> Nothing +decode_double_err :: A.Value -> Double+decode_double_err = fromMaybe (error "decode_double") . decode_double++decode_number_err :: A.Value -> Either Integer Double+decode_number_err = fromMaybe (error "decode_number") . decode_number+ decode_word8 :: A.Value -> Maybe Word8 decode_word8 j =-    case decode_number j of-      Just (Left i) -> if i < 256-                       then Just (fromIntegral i)-                       else Nothing+    case decode_integer j of+      Just i -> if i < 256+                then Just (fromIntegral i)+                else Nothing       _ -> Nothing  decode_datum :: A.Value -> Maybe Datum decode_datum j =     case j of-      A.Number (N.I n) -> Just (Int64 (fromIntegral n))-      A.Number (N.D n) -> Just (Double n)+      A.Number _ -> case decode_number_err j of+                      Left n -> if in_int32 n+                                then Just (Int32 (fromIntegral n))+                                else Just (Int64 (fromIntegral n))+                      Right n -> if True+                                 then Just (Float (realToFrac n))+                                 else Just (Double n)       A.String t -> Just (string (T.unpack t))       _ -> case decode_assoc j of              Just ("blob",A.Array v) ->@@ -98,6 +124,6 @@                  case mapM decode_word8 (V.toList v) of                    Just [p,q,r,s] -> Just (midi (p,q,r,s))                    _ -> Nothing-             Just ("timestamp",A.Number (N.D n)) -> Just (TimeStamp n)+             Just ("timestamp",n) -> Just (TimeStamp (decode_double_err n))              _ -> Nothing 
+ Sound/OSC/Type/JSON/Math.hs view
@@ -0,0 +1,44 @@+module Sound.OSC.Type.JSON.Math where++import Data.Int {- base -}+import Data.Ratio {- base -}+import Data.Word {- base -}++in_range :: (Integral r,Integral n) => r -> r -> n -> Bool+in_range l r n =+    let f :: Integral i => i -> Integer+        f = fromIntegral+    in f n >= f l && f n <= f r++-- > map in_int8 [-129,-128,0,127,128]+in_int8 :: Integral a => a -> Bool+in_int8 = in_range (minBound::Int8) (maxBound::Int8)++in_int16 :: Integral a => a -> Bool+in_int16 = in_range (minBound::Int16) (maxBound::Int16)++in_int32 :: Integral a => a -> Bool+in_int32 = in_range (minBound::Int32) (maxBound::Int32)++in_int64 :: Integral a => a -> Bool+in_int64 = in_range (minBound::Int64) (maxBound::Int64)++-- * Rational number predicates++-- | Is /n/ integral, ie. is 'denominator' @1@.+ratio_is_integral :: Integral n => Ratio n -> Bool+ratio_is_integral = (== 1) . denominator++-- | Is /n/ integral, and '<=' to /m/.+ratio_is_bounded_integral :: Integral n => n -> Ratio n -> Bool+ratio_is_bounded_integral m n =+    ratio_is_integral n &&+    numerator n <= m++-- | Is /n/ integral and in range for 'Int'.+ratio_is_int :: Integral n => Ratio n -> Bool+ratio_is_int = ratio_is_bounded_integral (fromIntegral (maxBound::Int))++-- | Is /n/ integral and in range for 'Word8'.+ratio_is_word8 :: Integral n => Ratio n -> Bool+ratio_is_word8 = ratio_is_bounded_integral (fromIntegral (maxBound::Word8))
hosc-json.cabal view
@@ -1,25 +1,25 @@ Name:              hosc-json-Version:           0.14+Version:           0.15 Synopsis:          Haskell Open Sound Control JSON Serialisation Description:       hosc-json License:           GPL Category:          Sound-Copyright:         (c) Rohan Drape, 2013+Copyright:         (c) Rohan Drape, 2013-2014 Author:            Rohan Drape Maintainer:        rd@slavepianos.org Stability:         Experimental-Homepage:          http://rd.slavepianos.org/?t=hosc-json-Tested-With:       GHC == 7.6.1+Homepage:          http://rd.slavepianos.org/t/hosc-json+Tested-With:       GHC == 7.8.2 Build-Type:        Simple Cabal-Version:     >= 1.8 Data-Files:        README  Library-  Build-Depends:   aeson,+  Build-Depends:   aeson >= 0.7,                    attoparsec,                    base == 4.*,                    bifunctors,-                   hosc == 0.14,+                   hosc == 0.15.*,                    bytestring,                    json,                    text,@@ -29,6 +29,7 @@   GHC-Options:     -Wall -fwarn-tabs   Exposed-modules: Sound.OSC.Type.JSON                    Sound.OSC.Type.JSON.Aeson+                   Sound.OSC.Type.JSON.Math  Source-Repository  head   Type:            darcs