@@ -37,8 +37,9 @@ import Data.Maybe ( fromMaybe )
37
37
import Data.List ( unfoldr )
38
38
import Data.Char ( isAlpha , isAlphaNum )
39
39
40
- import System.FilePath ( (</>) , (<.>) , takeDirectory , takeExtension )
41
- import System.Directory ( copyFile , createDirectoryIfMissing , getDirectoryContents )
40
+ import System.FilePath ( (</>) , (<.>) , takeBaseName , takeDirectory , takeExtension )
41
+ import System.Directory ( copyFile , createDirectoryIfMissing )
42
+ import System.Directory.Extra ( listFilesRecursive )
42
43
import System.Process ( spawnProcess , readProcess , waitForProcess )
43
44
import System.Exit ( ExitCode (.. ) )
44
45
import System.Environment ( setEnv )
@@ -71,8 +72,8 @@ initCodeBlocks dependenciesOpt = do
71
72
72
73
-- add hooks for writing out files (and possibly compiling the project)
73
74
let finalizer = case dependenciesOpt of
74
- Nothing -> fileFinalizer
75
- Just deps -> fileFinalizer *> cargoFinalizer [] deps
75
+ Nothing -> fileFinalizer True
76
+ Just deps -> fileFinalizer False *> cargoFinalizer [] deps
76
77
addModFinalizer finalizer
77
78
78
79
-- add a module state
@@ -150,24 +151,22 @@ cargoFinalizer :: [String] -- ^ Extra @cargo@ arguments
150
151
-> [(String , String )] -- ^ Dependencies
151
152
-> Q ()
152
153
cargoFinalizer extraArgs dependencies = do
153
- (pkg, mods ) <- currentFile
154
+ (pkg, _ ) <- currentFile
154
155
155
- let dir = " .inline-rust" </> pkg
156
- thisFile = foldr1 ( </>) mods <.> " rs "
156
+ let pkgDir = " .inline-rust" </> pkg
157
+ srcDir = pkgDir </> " src "
157
158
crate = " quasiquote_" ++ pkg
158
159
159
- nameFiles <- map (dir </> ) . filter ((" .ffinames" == ) . takeExtension) <$> runIO (getDirectoryContents dir)
160
- runIO $ print nameFiles
160
+ nameFiles <- filter ((" .ffinames" == ) . takeExtension) <$> runIO (listFilesRecursive srcDir)
161
161
names <- runIO $ concat <$> forM nameFiles (fmap lines . readFile )
162
- runIO $ print names
163
162
ffiFakeSig <- [t | IO () |]
164
163
forM_ names $ \ name -> do
165
164
name' <- newName $ name <> " _fake"
166
165
let ffiImport = ForeignD (ImportF CCall Unsafe name name' ffiFakeSig)
167
166
addTopDecls [ffiImport]
168
167
169
168
-- Make contents of a @Cargo.toml@ file
170
- let cargoToml = dir </> " Cargo" <.> " toml"
169
+ let cargoToml = pkgDir </> " Cargo" <.> " toml"
171
170
cargoSrc = unlines [ " [package]"
172
171
, " name = \" " ++ crate ++ " \" "
173
172
, " version = \" 0.0.0\" "
@@ -178,11 +177,11 @@ cargoFinalizer extraArgs dependencies = do
178
177
]
179
178
180
179
, " [lib]"
181
- , " path = \" " ++ thisFile ++ " \" "
182
180
, " crate-type = [\" staticlib\" ]"
183
181
]
184
- runIO $ createDirectoryIfMissing True dir
185
- runIO $ writeFile cargoToml cargoSrc
182
+ runIO $ do
183
+ createDirectoryIfMissing True pkgDir
184
+ writeFile cargoToml cargoSrc
186
185
187
186
-- Run Cargo to compile the project
188
187
--
@@ -242,12 +241,22 @@ rustcErrMsg = "Rust source file associated with this module failed to compile"
242
241
-- a module. This emits into a file in the @.inline-rust@ directory all of the
243
242
-- Rust code we have produced while processing the current files contexts and
244
243
-- quasiquotes.
245
- fileFinalizer :: Q ()
246
- fileFinalizer = do
244
+ fileFinalizer :: Bool -> Q ()
245
+ fileFinalizer submodule = do
247
246
(pkg, mods) <- currentFile
248
247
249
- let dir = " .inline-rust" </> pkg
250
- thisFile = foldr1 (</>) mods
248
+ let pkgDir = " .inline-rust" </> pkg
249
+ srcDir = pkgDir </> " src"
250
+ thisFile = if submodule then foldr1 (</>) mods else " lib"
251
+
252
+ when submodule $ do
253
+ let modPaths = tail $ (srcDir </> ) <$> scanl1 (</>) mods
254
+ forM_ modPaths $ \ modPath -> runIO $ do
255
+ let modName = takeBaseName modPath
256
+ modDir = takeDirectory modPath
257
+ modFile = modDir </> " mod.rs"
258
+ createDirectoryIfMissing True modDir
259
+ appendFile modFile $ " pub mod " <> modName <> " ;\n "
251
260
252
261
-- Figure out what we are putting into this file
253
262
Just cb <- getQ
@@ -262,13 +271,13 @@ fileFinalizer = do
262
271
$ " "
263
272
264
273
-- Write out the file
265
- let filepath = dir </> thisFile <.> " rs"
274
+ let filepath = srcDir </> thisFile <.> " rs"
266
275
runIO $ do
267
276
createDirectoryIfMissing True $ takeDirectory filepath
268
277
writeFile filepath code
269
278
270
279
Just (FFINames names) <- getQ
271
- let namesFile = dir </> foldr1 (<.>) mods <.> " ffinames"
280
+ let namesFile = srcDir </> foldr1 (<.>) mods <.> " ffinames"
272
281
runIO . writeFile namesFile . unlines $ names
273
282
274
283
-- | Figure out what file we are currently in.
0 commit comments