-- | -- Module : Robotics.ROS.Msg.Render -- Copyright : Alexander Krupenkin 2016 -- License : BSD3 -- -- Maintainer : mail@akru.me -- Stability : experimental -- Portability : POSIX / WIN32 -- -- The ROS message language builder from abstract message definition. -- module Robotics.ROS.Msg.Render ( -- * Lazy Text builder render -- * Strict Text render , renderT ) where import Data.Text.Lazy.Builder (Builder, fromText, fromString, toLazyText) import Data.Text.Lazy (toStrict) import Data.Char (toLower) import Data.Monoid ((<>)) import Data.Text (Text) import Robotics.ROS.Msg.Types -- | Builder creator from 'FieldType' rosType :: FieldType -> Builder rosType (Simple t) = fromString $ fmap toLower $ drop 1 $ show t rosType (Custom t) = fromText t rosType (Array t) = rosType t <> "[]" rosType (FixedArray l t) = rosType t <> "[" <> fromString (show l) <> "]" -- | Create lazy text builder from message definition -- -- Render formal ROS message definition according to: -- -- * comments removed -- -- * whitespace removed -- -- * package names of dependencies removed -- -- * constants reordered ahead of other declarations -- from http://www.ros.org/wiki/ROS/Technical%20Overview -- -- The @genmsg@ python implementation says: -- Compute the text used for md5 calculation. MD5 spec states that we -- removes comments and non-meaningful whitespace. We also strip -- packages names from type names. For convenience sake, constants are -- reordered ahead of other declarations, in the order that they were -- originally defined. -- render :: MsgDefinition -> Builder render [] = "" render msgdef = unlines1 (go <$> specOrder msgdef) where specOrder v = filter isConstant v ++ filter (not . isConstant) v unlines1 = foldl1 (\a b -> a <> "\n" <> b) go (Constant (typ, name) val) = rosType typ <> " " <> fromText name <> "=" <> fromText val go (Variable (typ, name)) = rosType typ <> " " <> fromText name isConstant x = case x of Constant _ _ -> True _ -> False -- | Render message definition to 'Text' instantly renderT :: MsgDefinition -> Text renderT = toStrict . toLazyText . render