|
| 1 | +{-# LANGUAGE NoMonomorphismRestriction #-} |
| 2 | +{-# LANGUAGE FlexibleContexts #-} |
| 3 | +{-# LANGUAGE TypeFamilies #-} |
| 4 | + |
| 5 | +import Diagrams.Prelude |
| 6 | +import Diagrams.Backend.SVG.CmdLine |
| 7 | +import Data.List (isPrefixOf) |
| 8 | + |
| 9 | +splitOn :: Eq a => [a] -> [a] -> [[a]] |
| 10 | +splitOn delim str = go str |
| 11 | + where |
| 12 | + go [] = [[]] |
| 13 | + go s |
| 14 | + | delim `isPrefixOf` s = [] : go (drop (length delim) s) |
| 15 | + | otherwise = |
| 16 | + let (c:cs) = s |
| 17 | + (x:xs) = go cs |
| 18 | + in (c:x) : xs |
| 19 | + |
| 20 | +------------------------------------------------------------------------------- |
| 21 | +-- Utilities |
| 22 | +------------------------------------------------------------------------------- |
| 23 | + |
| 24 | +title1 t = |
| 25 | + vsep 0.3 [ text line # fontSizeL 0.3 # bold | line <- splitOn "\n" t ] |
| 26 | +title2 t = text t # fontSizeL 0.2 # bold |
| 27 | + |
| 28 | +textBox x y t = t <> strutX x <> strutY y |
| 29 | + |
| 30 | +item1 t = text t # fontSizeL 0.25 |
| 31 | +enumerate items = vsep 0.3 [ textBox 2.0 0.4 (item1 i) | i <- items ] |
| 32 | + |
| 33 | +boxedXY :: Double -> Double -> Diagram B -> Diagram B |
| 34 | +boxedXY w h content = content # centerXY <> rect w h # lw thin |
| 35 | + |
| 36 | +boxedEnum x y items = |
| 37 | + let list = enumerate items |
| 38 | + in boxedXY x y (list # centerXY) |
| 39 | + |
| 40 | +titleW = 2.0 |
| 41 | +titleH = 0.5 |
| 42 | + |
| 43 | +boxedTitledEnum1 x y title items = |
| 44 | + let ttext = textBox titleW titleH (title1 title) |
| 45 | + list = enumerate items |
| 46 | + in boxedXY x y (vsep 0 [ttext, boxedXY x (y - titleH) (list # centerXY)]) |
| 47 | + |
| 48 | +connect1 = connectOutside' (with & arrowHead .~ tri & headLength .~ global 0.2) |
| 49 | + |
| 50 | +coreOval :: String -> Diagram B |
| 51 | +coreOval tag = |
| 52 | + textBox 2.0 0.5 (title1 tag # centerXY) |
| 53 | + <> ellipseXY 1.5 0.75 # fc lightblue # lw medium |
| 54 | + |
| 55 | +------------------------------------------------------------------------------- |
| 56 | +-- streamly-core diagram |
| 57 | +------------------------------------------------------------------------------- |
| 58 | + |
| 59 | +bigBoxW = 12 |
| 60 | +bigBoxH = 4 |
| 61 | +centerBoxW = bigBoxH |
| 62 | +centerBoxH = bigBoxH |
| 63 | + |
| 64 | +box1 = boxedXY bigBoxW bigBoxH |
| 65 | +box2 = boxedXY centerBoxW centerBoxH |
| 66 | + |
| 67 | +bigBoxSubContent = boxedTitledEnum1 (bigBoxW / 3) (bigBoxH - titleH) |
| 68 | + |
| 69 | +streamsBox :: Diagram B |
| 70 | +streamsBox = |
| 71 | + let prod = bigBoxSubContent "Generation" ["Stream", "StreamK", "Unfold"] |
| 72 | + transf = bigBoxSubContent "Transformation" ["Scanl"] |
| 73 | + cons = bigBoxSubContent "Consumption" ["Fold", "Parser", "ParserK"] |
| 74 | + row = hsep 0 [prod, transf, cons] |
| 75 | + title = textBox titleW titleH (title1 "Streams") |
| 76 | + content = vsep 0 [title, row # centerXY] |
| 77 | + in box1 (content # centerXY) |
| 78 | + |
| 79 | +arraysBox :: Diagram B |
| 80 | +arraysBox = |
| 81 | + let immut = bigBoxSubContent "Immutable" ["Array", "Array.Generic"] |
| 82 | + mut = bigBoxSubContent "Mutable" ["MutArray", "MutArray.Generic", "RingArray"] |
| 83 | + ser = bigBoxSubContent "Serialization" ["MutByteArray", "Unbox", "Serialize"] |
| 84 | + row = hsep 0 [immut, mut, ser] |
| 85 | + title = textBox titleW titleH (title1 "Arrays") |
| 86 | + content= vsep 0 [title, row # centerXY] |
| 87 | + in box1 (content # centerXY) |
| 88 | + |
| 89 | +fileSystemBox :: Diagram B |
| 90 | +fileSystemBox = |
| 91 | + let items = ["Console.Stdio", "FileIO", "DirIO", "Handle", "Path"] |
| 92 | + content = boxedTitledEnum1 centerBoxW centerBoxH "File System" items |
| 93 | + in box2 (content # centerXY) |
| 94 | + |
| 95 | +otherModulesBox :: Diagram B |
| 96 | +otherModulesBox = |
| 97 | + let unicode = boxedTitledEnum1 centerBoxW (centerBoxH * 2/3) "Unicode" ["Parser", "Stream", "String"] |
| 98 | + resmgmt = boxedTitledEnum1 centerBoxW (centerBoxH * 1/3) "Resource Management" ["Control.Exception"] |
| 99 | + content = vsep 0 [unicode, resmgmt] |
| 100 | + in box2 (content # centerXY) |
| 101 | + |
| 102 | +streamlyCore :: Diagram B |
| 103 | +streamlyCore = |
| 104 | + let center = coreOval "streamly-core\n(types and modules)" # named "core" |
| 105 | + topBox = streamsBox # named "streams" |
| 106 | + bottomBox = arraysBox # named "arrays" |
| 107 | + leftBox = fileSystemBox # named "fs" |
| 108 | + rightBox = otherModulesBox # named "others" |
| 109 | + |
| 110 | + placed = position |
| 111 | + [ (p2 (0,0), center) |
| 112 | + , (p2 (0,4), topBox) |
| 113 | + , (p2 (0,-4), bottomBox) |
| 114 | + , (p2 (-4,0), leftBox) |
| 115 | + , (p2 (4,0), rightBox) |
| 116 | + ] |
| 117 | + |
| 118 | + arrows = applyAll |
| 119 | + [ connect1 "core" "streams" |
| 120 | + , connect1 "core" "arrays" |
| 121 | + , connect1 "core" "fs" |
| 122 | + , connect1 "core" "others" |
| 123 | + ] |
| 124 | + in arrows placed |
| 125 | + |
| 126 | +------------------------------------------------------------------------------- |
| 127 | +-- streamly diagram |
| 128 | +------------------------------------------------------------------------------- |
| 129 | + |
| 130 | +concurrentStreamsBox :: Diagram B |
| 131 | +concurrentStreamsBox = |
| 132 | + let prod = bigBoxSubContent "Generation" ["Stream.Prelude"] |
| 133 | + transf = bigBoxSubContent "Transformation" ["Scanl.Prelude"] |
| 134 | + cons = bigBoxSubContent "Consumption" ["Fold.Prelude"] |
| 135 | + row = hsep 0 [prod, transf, cons] |
| 136 | + title = textBox titleW titleH (title1 "Concurrent Streams") |
| 137 | + content = vsep 0 [title, row # centerXY] |
| 138 | + in box1 (content # centerXY) |
| 139 | + |
| 140 | +networkBox :: Diagram B |
| 141 | +networkBox = |
| 142 | + let items = ["Network.Socket", "Network.Inet.TCP"] |
| 143 | + content = boxedTitledEnum1 centerBoxW centerBoxH "Network" items |
| 144 | + in box2 (content # centerXY) |
| 145 | + |
| 146 | +streamly :: Diagram B |
| 147 | +streamly = |
| 148 | + let center = coreOval "streamly" # named "streamly" |
| 149 | + topBox = concurrentStreamsBox # named "concurrent-streams" |
| 150 | + bottomBox = networkBox # named "network" |
| 151 | + |
| 152 | + placed = position |
| 153 | + [ (p2 (0,0), center) |
| 154 | + , (p2 (0,4), topBox) |
| 155 | + , (p2 (0,-4), bottomBox) |
| 156 | + ] |
| 157 | + |
| 158 | + arrows = applyAll |
| 159 | + [ connect1 "streamly" "concurrent-streams" |
| 160 | + , connect1 "streamly" "network" |
| 161 | + ] |
| 162 | + in arrows placed |
| 163 | + |
| 164 | +main :: IO () |
| 165 | +main = |
| 166 | + mainWith |
| 167 | + [ ("streamly-core", (streamlyCore # centerXY # pad 1.1)) |
| 168 | + , ("streamly", (streamly # centerXY # pad 1.1)) |
| 169 | + ] |
0 commit comments