@@ -37,8 +37,9 @@ import Data.Maybe ( fromMaybe )
3737import Data.List ( unfoldr )
3838import Data.Char ( isAlpha , isAlphaNum )
3939
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 )
4243import System.Process ( spawnProcess , readProcess , waitForProcess )
4344import System.Exit ( ExitCode (.. ) )
4445import System.Environment ( setEnv )
@@ -71,8 +72,8 @@ initCodeBlocks dependenciesOpt = do
7172
7273 -- add hooks for writing out files (and possibly compiling the project)
7374 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
7677 addModFinalizer finalizer
7778
7879 -- add a module state
@@ -150,24 +151,22 @@ cargoFinalizer :: [String] -- ^ Extra @cargo@ arguments
150151 -> [(String , String )] -- ^ Dependencies
151152 -> Q ()
152153cargoFinalizer extraArgs dependencies = do
153- (pkg, mods ) <- currentFile
154+ (pkg, _ ) <- currentFile
154155
155- let dir = " .inline-rust" </> pkg
156- thisFile = foldr1 ( </>) mods <.> " rs "
156+ let pkgDir = " .inline-rust" </> pkg
157+ srcDir = pkgDir </> " src "
157158 crate = " quasiquote_" ++ pkg
158159
159- nameFiles <- map (dir </> ) . filter ((" .ffinames" == ) . takeExtension) <$> runIO (getDirectoryContents dir)
160- runIO $ print nameFiles
160+ nameFiles <- filter ((" .ffinames" == ) . takeExtension) <$> runIO (listFilesRecursive srcDir)
161161 names <- runIO $ concat <$> forM nameFiles (fmap lines . readFile )
162- runIO $ print names
163162 ffiFakeSig <- [t | IO () |]
164163 forM_ names $ \ name -> do
165164 name' <- newName $ name <> " _fake"
166165 let ffiImport = ForeignD (ImportF CCall Unsafe name name' ffiFakeSig)
167166 addTopDecls [ffiImport]
168167
169168 -- Make contents of a @Cargo.toml@ file
170- let cargoToml = dir </> " Cargo" <.> " toml"
169+ let cargoToml = pkgDir </> " Cargo" <.> " toml"
171170 cargoSrc = unlines [ " [package]"
172171 , " name = \" " ++ crate ++ " \" "
173172 , " version = \" 0.0.0\" "
@@ -178,11 +177,11 @@ cargoFinalizer extraArgs dependencies = do
178177 ]
179178
180179 , " [lib]"
181- , " path = \" " ++ thisFile ++ " \" "
182180 , " crate-type = [\" staticlib\" ]"
183181 ]
184- runIO $ createDirectoryIfMissing True dir
185- runIO $ writeFile cargoToml cargoSrc
182+ runIO $ do
183+ createDirectoryIfMissing True pkgDir
184+ writeFile cargoToml cargoSrc
186185
187186 -- Run Cargo to compile the project
188187 --
@@ -242,12 +241,22 @@ rustcErrMsg = "Rust source file associated with this module failed to compile"
242241-- a module. This emits into a file in the @.inline-rust@ directory all of the
243242-- Rust code we have produced while processing the current files contexts and
244243-- quasiquotes.
245- fileFinalizer :: Q ()
246- fileFinalizer = do
244+ fileFinalizer :: Bool -> Q ()
245+ fileFinalizer submodule = do
247246 (pkg, mods) <- currentFile
248247
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 "
251260
252261 -- Figure out what we are putting into this file
253262 Just cb <- getQ
@@ -262,13 +271,13 @@ fileFinalizer = do
262271 $ " "
263272
264273 -- Write out the file
265- let filepath = dir </> thisFile <.> " rs"
274+ let filepath = srcDir </> thisFile <.> " rs"
266275 runIO $ do
267276 createDirectoryIfMissing True $ takeDirectory filepath
268277 writeFile filepath code
269278
270279 Just (FFINames names) <- getQ
271- let namesFile = dir </> foldr1 (<.>) mods <.> " ffinames"
280+ let namesFile = srcDir </> foldr1 (<.>) mods <.> " ffinames"
272281 runIO . writeFile namesFile . unlines $ names
273282
274283-- | Figure out what file we are currently in.
0 commit comments