1 module Databrary.Store.Filename 2 ( makeFilename 3 ) where 4 5 import qualified Data.ByteString as BS 6 import qualified Data.ByteString.Builder as BSB 7 import qualified Data.ByteString.Lazy as BSL 8 import Data.Char (isSpace) 9 import Data.List (intersperse) 10 import Data.Monoid ((<>)) 11 import qualified Data.Text as T 12 13 truncateFilename :: T.Text -> Int 14 truncateFilename s 15 | len <= maxlen = len 16 | otherwise = fr maxlen where 17 len = T.length s 18 fr n 19 | n < maxlen `div` 2 = maxlen 20 | isSpace (T.index s n) = n 21 | otherwise = fr $ pred n 22 maxlen = 32 23 24 buildFilename :: T.Text -> BSB.Builder 25 buildFilename t = fc (T.unpack t) len True where 26 len = truncateFilename t 27 fc [] _ _ = mempty 28 fc _ 0 _ = mempty 29 fc (c:s) n p 30 | c < ',' || c `elem` "/?\\" = if p then r True else BSB.char8 '_' <> r True 31 | otherwise = BSB.charUtf8 c <> r False 32 where r = fc s (pred n) 33 34 makeFilename :: [T.Text] -> BS.ByteString 35 makeFilename = BSL.toStrict . BSB.toLazyByteString . mconcat . intersperse (BSB.char8 '-') . map buildFilename