Skip to content

Commit 1b374cf

Browse files
committed
Unified ReadShow usage patterns
Unifies several common usage patterns of Network.Socket.ReadShow for types with bijective read/show definitions, consolidating reused boilerplate code to in-module functions
1 parent 827bb27 commit 1b374cf

File tree

5 files changed

+42
-29
lines changed

5 files changed

+42
-29
lines changed

Network/Socket/Options.hsc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,17 +430,16 @@ socketOptionBijection :: Bijection SocketOption String
430430
socketOptionBijection = Bijection{..}
431431
where
432432
cso = "CustomSockOpt"
433-
defFwd = \(CustomSockOpt (n,m)) -> cso++show n++"_"++show m
434-
defBwd s = case splitAt (length cso) s of
435-
("CustomSockOpt", nm) -> CustomSockOpt $ _parse nm
436-
_ -> error "socketOptionBijection: exception in WIP ReadShow code"
433+
unCSO = \(CustomSockOpt nm) -> nm
434+
defFwd = defShow cso unCSO _show
435+
defBwd = defRead cso CustomSockOpt _parse
437436
pairs = socketOptionPairs
438437

439438
instance Show SocketOption where
440439
show = forward socketOptionBijection
441440

442441
instance Read SocketOption where
443-
readPrec = P.lexP >>= \(P.Ident x) -> return $ backward socketOptionBijection x
442+
readPrec = tokenize $ backward socketOptionBijection
444443

445444

446445
foreign import CALLCONV unsafe "getsockopt"

Network/Socket/Posix/Cmsg.hsc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,13 @@ cmsgIdBijection :: Bijection CmsgId String
245245
cmsgIdBijection = Bijection{..}
246246
where
247247
defname = "CmsgId"
248-
defFwd = \(CmsgId l t) -> defname++show l++"_"++show t
249-
defBwd s =
250-
case splitAt (length defname) s of
251-
("CmsgId", nm) -> uncurry CmsgId $ _parse nm
252-
_ -> error "cmsgIdBijection: exception in WIP ReadShow code"
248+
unId = \(CmsgId l t) -> (l,t)
249+
defFwd = defShow defname unId _show
250+
defBwd = defRead defname (uncurry CmsgId) _parse
253251
pairs = cmsgIdPairs
254252

255253
instance Show CmsgId where
256254
show = forward cmsgIdBijection
257255

258256
instance Read CmsgId where
259-
readPrec = P.lexP >>= \(P.Ident x) -> return $ backward cmsgIdBijection x
257+
readPrec = tokenize $ backward cmsgIdBijection

Network/Socket/ReadShow.hs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
{-# LANGUAGE RecordWildCards #-}
2+
{-# LANGUAGE PatternGuards #-}
3+
24

35
module Network.Socket.ReadShow where
46

7+
import qualified Text.Read as P
8+
59
-- type alias for individual correspondences of a (possibly partial) bijection
610
type Pair a b = (a, b)
711

@@ -53,4 +57,24 @@ _parse :: (Read a, Read b) => String -> (a, b)
5357
_parse xy =
5458
let (xs, '_':ys) = break (=='_') xy
5559
in (read xs, read ys)
60+
{-# INLINE _parse #-}
61+
62+
-- | inverse function to _parse
63+
-- show a tuple as underscore-separated strings
64+
_show :: (Show a, Show b) => (a, b) -> String
65+
_show (x, y) = show x ++ "_" ++ show y
66+
67+
{-# INLINE defShow #-}
68+
defShow :: Eq a => String -> (a -> b) -> (b -> String) -> (a -> String)
69+
defShow name get sho = \x -> name ++ (sho . get $ x)
70+
71+
{-# INLINE defRead #-}
72+
defRead :: Read a => String -> (b -> a) -> (String -> b) -> (String -> a)
73+
defRead name set red = \s ->
74+
case splitAt (length name) s of
75+
(x, sn) | x == name -> set $ red sn
76+
_ -> error $ "defRead: unable to parse " ++ show s
5677

78+
{-# INLINE tokenize #-}
79+
tokenize :: (String -> a) -> P.ReadPrec a
80+
tokenize f = P.lexP >>= \(P.Ident x) -> return $ f x

Network/Socket/Types.hsc

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,18 +1331,15 @@ socktypeBijection :: Bijection SocketType String
13311331
socktypeBijection = Bijection{..}
13321332
where
13331333
gst = "GeneralSocketType"
1334-
defFwd = \(GeneralSocketType n) -> gst++show n
1335-
defBwd = \s ->
1336-
case splitAt (length gst) s of
1337-
("GeneralSocketType", sn) -> GeneralSocketType $ (read sn :: CInt)
1338-
_ -> error "socktypeBijection: exception in WIP ReadShow code"
1334+
defFwd = defShow gst packSocketType show
1335+
defBwd = defRead gst unpackSocketType read
13391336
pairs = socktypePairs
13401337

13411338
instance Show SocketType where
13421339
show = forward socktypeBijection
13431340

13441341
instance Read SocketType where
1345-
readPrec = P.lexP >>= \(P.Ident x) -> return $ backward socktypeBijection x
1342+
readPrec = tokenize $ backward socktypeBijection
13461343

13471344
familyPairs :: [Pair Family String]
13481345
familyPairs =
@@ -1419,18 +1416,15 @@ familyBijection :: Bijection Family String
14191416
familyBijection = Bijection{..}
14201417
where
14211418
gf = "GeneralFamily"
1422-
defFwd = \(GeneralFamily n) -> gf++show n
1423-
defBwd = \s ->
1424-
case splitAt (length gf) s of
1425-
("GeneralFamily", sn) -> GeneralFamily $ (read sn :: CInt)
1426-
_ -> error "familyBijection: exception in WIP ReadShow code"
1419+
defFwd = defShow gf packFamily show
1420+
defBwd = defRead gf unpackFamily read
14271421
pairs = familyPairs
14281422

14291423
instance Show Family where
14301424
show = forward familyBijection
14311425

14321426
instance Read Family where
1433-
readPrec = P.lexP >>= \(P.Ident x) -> return $ backward familyBijection x
1427+
readPrec = tokenize $ backward familyBijection
14341428

14351429
-- Print "n" instead of "PortNum n".
14361430
instance Show PortNumber where

Network/Socket/Win32/Cmsg.hsc

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,13 @@ cmsgIdBijection :: Bijection CmsgId String
202202
cmsgIdBijection = Bijection{..}
203203
where
204204
defname = "CmsgId"
205-
defFwd = \(CmsgId l t) -> defname++show l++"_"++show t
206-
defBwd s =
207-
case splitAt (length defname) s of
208-
("CmsgId", nm) -> uncurry CmsgId $ _parse nm
209-
_ -> error "cmsgIdBijection: exception in WIP ReadShow code"
205+
unId = \(CmsgId l t) -> (l,t)
206+
defFwd = defShow defname unId _show
207+
defBwd = defRead defname (uncurry CmsgId) _parse
210208
pairs = cmsgIdPairs
211209

212210
instance Show CmsgId where
213211
show = forward cmsgIdBijection
214212

215213
instance Read CmsgId where
216-
readPrec = P.lexP >>= \(P.Ident x) -> return $ backward cmsgIdBijection x
214+
readPrec = tokenize $ backward cmsgIdBijection

0 commit comments

Comments
 (0)