(.module: [library [lux {"-" [Module]} [abstract ["[0]" monad {"+" [Monad do]}]] [control ["[0]" try {"+" [Try]}] ["[0]" exception {"+" [exception:]}] [concurrency ["[0]" async {"+" [Async]} ("[1]\[0]" monad)]] ["<>" parser ["<[0]>" binary]]] [data [binary {"+" [Binary]}] ["[0]" text ["%" format {"+" [format]}]] [collection ["[0]" dictionary {"+" [Dictionary]}] ["[0]" row]] [format ["[0]" tar]]] [tool [compiler [meta [archive [descriptor {"+" [Module]}]]]]] [world ["[0]" 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))