@@ -2,16 +2,28 @@
22{-# LANGUAGE OverloadedStrings #-}
33module Elm.Name
44 ( Name
5+ -- utilities
56 , length
7+ , contains
68 , startsWith
79 , drop
10+ -- conversions
11+ , toText
812 , toString
913 , toBuilder
14+ , toDotlessBuilder
1015 , toShort
16+ -- helpers
1117 , addIndex
1218 , addSafeIndex
1319 , toCompositeName
20+ , sepBy
21+ -- create
1422 , fromForeignPtr
23+ , fromString
24+ , fromLetter
25+ , fromText
26+ -- interned
1527 , int, float, bool, char, string
1628 , maybe, list, array, tuple, jsArray
1729 , task, router, cmd, sub, platform, browser
@@ -23,11 +35,12 @@ module Elm.Name
2335
2436
2537import Prelude hiding (drop, length, maybe, negate)
38+import Data.Binary
2639import qualified Data.ByteString.Builder as B
2740import qualified Data.ByteString.Internal as B
2841import qualified Data.ByteString.Short as S
2942import qualified Data.Char as Char
30−import qualified Data.Set as Set
43+import qualified Data.String as String
3144import qualified Data.Text as Text
3245import qualified Data.Text.Encoding as Text
3346import Data.Word (Word8)
@@ -38,32 +51,52 @@ import Foreign.ForeignPtr (ForeignPtr)
3851-- NAME
3952
4053
41−type Name = Text.Text
54+newtype Name = Name { _name :: Text.Text }
55+ deriving (Eq, Ord)
4256
4357
4458length :: Name -> Int
45−length =
46− Text.length
59+length (Name name) =
60+ Text.length name
61+
62+
63+contains :: Word8 -> Name -> Bool
64+contains word (Name name) =
65+ Text.isInfixOf (Text.singleton (Char.chr (fromIntegral word))) name
4766
4867
4968startsWith :: Name -> Name -> Bool
50−startsWith =
51− Text.isPrefixOf
69+startsWith (Name prefix) (Name name) =
70+ Text.isPrefixOf prefix name
5271
5372
5473drop :: Int -> Name -> Name
55−drop =
56− Text.drop
74+drop numBytes (Name name) =
75+ Name (Text.drop numBytes name)
76+
77+
78+
79+-- CONVERSIONS
80+
81+
82+toText :: Name -> Text.Text
83+toText (Name name) =
84+ name
5785
5886
5987toString :: Name -> String
60−toString =
61− Text.unpack
88+toString (Name name) =
89+ Text.unpack name
6290
6391
6492toBuilder :: Name -> B.Builder
65−toBuilder =
66− Text.encodeUtf8Builder
93+toBuilder (Name name) =
94+ Text.encodeUtf8Builder name
95+
96+
97+toDotlessBuilder :: Name -> B.Builder
98+toDotlessBuilder (Name name) =
99+ Text.encodeUtf8Builder (Text.replace "." "$" name)
67100
68101
69102toShort :: Name -> S.ShortByteString
@@ -72,31 +105,66 @@ toShort name =
72105
73106
74107addIndex :: Name -> Int -> Name
75−addIndex name index =
76− Text.append name (Text.pack (show index))
108+addIndex (Name name) index =
109+ Name (Text.append name (Text.pack (show index)))
77110
78111
79112addSafeIndex :: Name -> Int -> Name
80−addSafeIndex name index =
81− Text.append name $ Text.pack $
113+addSafeIndex (Name name) index =
114+ Name $ Text.append name $ Text.pack $
82115 if Char.isDigit (Text.last name) then
83116 '_' : show index
84117 else
85118 show index
86119
87120
88−toCompositeName :: Set.Set Name -> Name
121+toCompositeName :: [Name] -> Name
89122toCompositeName names =
90− Text.cons '$' (Text.intercalate "$" (Set.toList names))
123+ Name (Text.cons '$' (Text.intercalate "$" (map _name names)))
91124
92125
126+sepBy :: Word8 -> Name -> Name -> Name
127+sepBy sep (Name home) (Name name) =
128+ Name (Text.concat [ home, Text.singleton (Char.chr (fromIntegral sep)), name ])
93129
94−-- FROM PARSER
130+
131+
132+-- CREATE NAMES
95133
96134
97135fromForeignPtr :: ForeignPtr Word8 -> Int -> Int -> Name
98136fromForeignPtr fptr offset len =
99− Text.decodeUtf8 (B.PS fptr offset len)
137+ Name (Text.decodeUtf8 (B.PS fptr offset len))
138+
139+
140+fromString :: String -> Name
141+fromString str =
142+ Name (Text.pack str)
143+
144+
145+{- Takes a letter from 0 to 25 -}
146+fromLetter :: Int -> Name
147+fromLetter letter =
148+ Name (Text.singleton (Char.chr (97 + letter)))
149+
150+
151+fromText :: Text.Text -> Name
152+fromText =
153+ Name
154+
155+
156+
157+-- INSTANCES
158+
159+
160+instance String.IsString Name where
161+ fromString str =
162+ Name (Text.pack str)
163+
164+
165+instance Binary Name where
166+ put (Name name) = put name
167+ get = Name <$> get
100168
101169
102170