module Codec.Text.Multipath ( Multipath, fromBytes, toBytes, fromString, toString ) where import qualified Codec.Binary.UTF8.String as UTF8 import Text.Parsec.String (Parser) import Text.Parsec.Combinator import Text.Parsec.Char import Text.Parsec.Prim import Text.Parsec.Error import Data.Word import Data.Either type Multipath = [String] separatorChar :: Char separatorChar = '/' escapeChar :: Char escapeChar = '\\' fromBytes :: [Word8] -> Either String Multipath fromBytes = fromString . UTF8.decode fromString :: String -> Either String Multipath fromString = either (Left . show) (Right) . parse parseMultihash "mutipath" toBytes :: Multipath -> [Word8] toBytes = UTF8.encode . toString toString :: Multipath -> String toString = concat . map ((separatorChar :) . concat . map escape) where escape ch | ch ==separatorChar = [escapeChar, separatorChar] | ch == escapeChar = [escapeChar, escapeChar] | otherwise = [ch] parseMultihash :: Parser Multipath parseMultihash = do parts <- many $ do char separatorChar parsePart eof return parts parsePart :: Parser String parsePart = many $ (noneOf [separatorChar, escapeChar] <|> parseEscapedChar) parseEscapedChar :: Parser Char parseEscapedChar = do char escapeChar anyChar