Skip to content

Commit e852790

Browse files
committed
allow submodules to have the same name as path components
1 parent 0a9b6f7 commit e852790

File tree

2 files changed

+26
-22
lines changed

2 files changed

+26
-22
lines changed

inline-rust.cabal

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ library
4747
, ScopedTypeVariables
4848

4949
build-depends: base >=4.9 && <5.0
50-
, extra >=0.5
5150
, language-rust >=0.2.0
5251
, prettyprinter >=1.1
5352
, process >=1.4

src/Language/Rust/Inline/Internal.hs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,15 @@ import Language.Rust.Inline.Context
3030
import Language.Haskell.TH
3131
import Language.Haskell.TH.Syntax
3232

33-
import Control.Monad ( when, forM, forM_ )
33+
import Control.Monad ( filterM, forM, forM_, when )
3434
import Data.Typeable ( Typeable )
3535
import Data.Monoid ( Endo(..) )
3636
import Data.Maybe ( fromMaybe )
37-
import Data.List ( nub, unfoldr )
38-
import Data.Char ( isAlpha, isAlphaNum, isUpperCase )
37+
import Data.List ( unfoldr )
38+
import Data.Char ( isAlpha, isAlphaNum )
3939

4040
import System.FilePath ( (</>), (<.>), takeBaseName, takeDirectory, takeExtension )
41-
import System.Directory ( copyFile, removeFile, createDirectoryIfMissing )
42-
import System.Directory.Extra ( listFilesRecursive, listDirectories, listFiles )
41+
import System.Directory ( copyFile, removeFile, createDirectoryIfMissing, listDirectory, doesDirectoryExist )
4342
import System.Process ( spawnProcess, readProcess, waitForProcess )
4443
import System.Exit ( ExitCode(..) )
4544
import System.Environment ( setEnv )
@@ -62,14 +61,14 @@ newtype FFINames = FFINames [String]
6261
-- | Initialize the 'CodeBlocks' of the current module. Crash if it is already
6362
-- intialized. This must be called exactly once.
6463
initCodeBlocks :: Maybe [(String,String)] -- ^ dependencies, if crate root
65-
-> Q ()
64+
-> Q ()
6665
initCodeBlocks dependenciesOpt = do
6766
-- check if there is already something there
6867
cb <- getQ
6968
case cb of
7069
Nothing -> pure ()
7170
Just (CodeBlocks _) -> fail "initCodeBlocks: CodeBlocks already initialized"
72-
71+
7372
-- add hooks for writing out files (and possibly compiling the project)
7473
let finalizer = case dependenciesOpt of
7574
Nothing -> fileFinalizer
@@ -84,7 +83,7 @@ initCodeBlocks dependenciesOpt = do
8483
-- | Emit a raw 'String' of Rust code into the current 'ModuleState'.
8584
emitCodeBlock :: String -> Q [Dec]
8685
emitCodeBlock code = do
87-
Just (CodeBlocks cbs) <- getQ
86+
Just (CodeBlocks cbs) <- getQ
8887
putQ (CodeBlocks (cbs . showString code . showString "\n"))
8988
pure []
9089

@@ -125,7 +124,7 @@ extendContext :: Q Context -> Q [Dec]
125124
extendContext qExtension = do
126125
extension <- qExtension
127126
ctx <- getContext
128-
putQ (ctx <> extension)
127+
putQ (ctx <> extension)
129128
pure []
130129

131130
-- | Search in a 'Context' for the Haskell type corresponding to a Rust type.
@@ -156,16 +155,22 @@ cargoFinalizer extraArgs dependencies = do
156155
srcDir = pkgDir </> "src"
157156
crate = "quasiquote_" ++ pkg
158157

159-
nameFiles <- filter ((".ffinames" ==) . takeExtension) <$> runIO (listFilesRecursive srcDir)
158+
nameFiles <- fmap (srcDir </>) . filter ((".ffinames" ==) . takeExtension) <$> runIO (listDirectory srcDir)
160159

161160
let modDir dir = do
162-
subdirs <- listDirectories dir
163-
mapM_ modDir subdirs
164-
srcs <- filter (\file -> takeExtension file == ".rs" && isUpperCase (head $ takeBaseName file)) <$> listFiles dir
165-
let modules = nub $ takeBaseName <$> (subdirs <> srcs)
166-
writeFile (dir </> "mod.rs") . unlines . concat $ [ ["", "pub mod " <> name <> ";", "pub use self::" <> name <> "::*;"]
161+
entries <- fmap (dir </>) <$> listDirectory dir
162+
modDirs <- filterM doesDirectoryExist entries
163+
let modSrcs = filter ((".rs" ==) . takeExtension) entries
164+
mapM_ modDir modDirs
165+
let modules = takeBaseName <$> (modDirs <> modSrcs)
166+
writeFile (dir </> "mod.rs") . unlines . concat $ [ ["pub mod " <> name <> ";", "pub use self::" <> name <> "::*;", ""]
167167
| name <- modules
168168
]
169+
let currentModSrc = takeBaseName dir <.> "rs"
170+
when (currentModSrc `elem` modSrcs) $ do
171+
currentModContents <- readFile (dir </> currentModSrc)
172+
removeFile $ dir </> currentModSrc
173+
appendFile (dir </> "mod.rs") currentModContents
169174

170175
runIO $ do
171176
modDir srcDir
@@ -216,13 +221,13 @@ cargoFinalizer extraArgs dependencies = do
216221
let cargoArgs = [ "build"
217222
, "--release"
218223
, "--manifest-path=" ++ cargoToml
219-
] ++ extraArgs
224+
] ++ extraArgs
220225
msgFormat = [ "--message-format=json" ]
221226

222227
ec <- runIO $ spawnProcess "cargo" cargoArgs >>= waitForProcess
223228
when (ec /= ExitSuccess)
224229
(reportError rustcErrMsg)
225-
230+
226231
-- Run Cargo again to get the static library path
227232
jOuts <- runIO $ readProcess "cargo" (cargoArgs ++ msgFormat) ""
228233

@@ -263,12 +268,12 @@ fileFinalizer = do
263268

264269
let pkgDir = ".inline-rust" </> pkg
265270
srcDir = pkgDir </> "src"
266-
thisFile = foldr1 (</>) mods
271+
modDir = foldr1 (</>) mods
267272

268273
-- Figure out what we are putting into this file
269274
Just cb <- getQ
270275
Just (Context (_,_,impls)) <- getQ
271-
let code = showsCodeBlocks cb
276+
let code = showsCodeBlocks cb
272277
. showString "pub mod marshal {\n"
273278
. showString "#[allow(unused_imports)] use super::*;\n"
274279
. showString "pub trait MarshalInto<T> { fn marshal(self) -> T; }\n"
@@ -278,8 +283,8 @@ fileFinalizer = do
278283
$ ""
279284

280285
-- Write out the file
281-
let filepath = srcDir </> thisFile <.> "rs"
282-
let namesFile = srcDir </> thisFile <.> "ffinames"
286+
let filepath = srcDir </> modDir <.> ".rs"
287+
let namesFile = srcDir </> foldr1 (<.>) mods <.> "ffinames"
283288
Just (FFINames names) <- getQ
284289
runIO $ do
285290
createDirectoryIfMissing True $ takeDirectory filepath

0 commit comments

Comments
 (0)