(.module: [library [lux "*" [abstract [monad {"+" [do]}]] [control ["[0]" io {"+" [IO]}] ["[0]" try {"+" [Try]}] ["[0]" exception {"+" [exception:]}]] [data ["[0]" product] [text ["%" format {"+" [format]}]]] [tool [compiler ["[0]" version] ["[0]" language "_" ["[1]/[0]" lux "_" ["[1]" version]]]]] [world [net {"+" [URL]} [uri {"+" [URI]}] ["[0]" http "_" ["[1]" client] ["[1]/[0]" status] ["@[1]" /]]]]]] ["[0]" // ["[1][0]" identity {"+" [Identity]}] ["/[1]" // "_" ["[1][0]" artifact {"+" [Version Artifact]} [extension {"+" [Extension]}]]]]) (type: .public Address URL) (template [] [(exception: .public ( [url URL status Nat]) (exception.report ["URL" (%.text url)] ["Status Code" (%.nat status)]))] [download_failure] [upload_failure] ) (def: .public (uri version_template artifact extension) (-> Version Artifact Extension URI) (format (///artifact.uri version_template artifact) extension)) (def: .public user_agent (format "LuxAedifex/" (version.format language/lux.version))) (def: base_headers (List [Text Text]) (list ["User-Agent" ..user_agent])) (implementation: .public (repository http identity address) (All (_ s) (-> (http.Client IO) (Maybe Identity) Address (//.Repository IO))) (def: description address) (def: (download uri) (do [! (try.with io.monad)] [[status message] (: (IO (Try (@http.Response IO))) (http.get (format address uri) (http.headers ..base_headers) #.None http))] (case status (^ (static http/status.ok)) (\ ! each product.right ((value@ #@http.body message) #.None)) _ (do ! [_ ((value@ #@http.body message) (#.Some 0))] (\ io.monad in (exception.except ..download_failure [(format address uri) status])))))) (def: (upload uri content) (do (try.with io.monad) [[status message] (: (IO (Try (@http.Response IO))) (http.put (format address uri) (http.headers (case identity #.None ..base_headers (#.Some [user password]) (list& ["Authorization" (//identity.basic_auth user password)] ..base_headers))) (#.Some content) http)) _ ((value@ #@http.body message) (#.Some 0))] (case status (^ (static http/status.created)) (in []) _ (\ io.monad in (exception.except ..upload_failure [(format address uri) status]))))) )