(.module: [library [lux (#- Module) [abstract ["." monad (#+ Monad do)]] [control ["." try (#+ Try)] ["." exception (#+ exception:)] [concurrency ["." async (#+ Async) ("#\." monad)]] ["<>" parser ["<.>" binary]]] [data [binary (#+ Binary)] ["." text ["%" format (#+ format)]] [collection ["." dictionary (#+ Dictionary)] ["." row]] [format ["." tar]]] [tool [compiler [meta [archive [descriptor (#+ Module)]]]]] [world ["." file]]]] [// [cli (#+ Library)]]) (def: Action (type (All [a] (Async (Try a))))) (exception: .public useless_tar_entry) (exception: .public (duplicate {library Library} {module Module}) (exception.report ["Module" (%.text module)] ["Library" (%.text library)])) (type: .public Import (Dictionary file.Path Binary)) (def: (import_library system library import) (-> (file.System Async) Library Import (Action Import)) (let [! async.monad] (|> library (\ system read) (\ ! each (let [! try.monad] (|>> (\ ! each (.result tar.parser)) (\ ! conjoint) (\ ! each (|>> row.list (monad.mix ! (function (_ entry import) (case entry (#tar.Normal [path instant mode ownership content]) (let [path (tar.from_path path)] (case (dictionary.has' path (tar.data content) import) (#try.Failure error) (exception.except ..duplicate [library path]) import' import')) _ (exception.except ..useless_tar_entry []))) import))) (\ ! conjoint))))))) (def: .public (import system libraries) (-> (file.System Async) (List Library) (Action Import)) (monad.mix (: (Monad Action) (try.with async.monad)) (..import_library system) (dictionary.empty text.hash) libraries))