(.module: [library [lux #* [abstract [monad (#+ do)]] [control [io (#+ IO)] ["." try (#+ Try)] [concurrency ["." async (#+ Async)] ["." stm]]] [data [binary (#+ Binary)]] [world [net [uri (#+ URI)]]]]]) (type: .public (Repository !) (Interface (: Text description) (: (-> URI (! (Try Binary))) download) (: (-> URI Binary (! (Try Any))) upload))) (def: .public (async repository) (-> (Repository IO) (Repository Async)) (implementation (def: description (\ repository description)) (def: (download uri) (async.future (\ repository download uri))) (def: (upload uri content) (async.future (\ repository upload uri content))) )) (type: .public (Mock s) (Interface (: Text the_description) (: (-> URI s (Try [s Binary])) on_download) (: (-> URI Binary s (Try s)) on_upload))) (def: .public (mock mock init) (All [s] (-> (Mock s) s (Repository Async))) (let [state (stm.var init)] (implementation (def: description (\ mock the_description)) (def: (download uri) (stm.commit! (do {! stm.monad} [|state| (stm.read state)] (case (\ mock on_download uri |state|) (#try.Success [|state| output]) (do ! [_ (stm.write |state| state)] (in (#try.Success output))) (#try.Failure error) (in (#try.Failure error)))))) (def: (upload uri content) (stm.commit! (do {! stm.monad} [|state| (stm.read state)] (case (\ mock on_upload uri content |state|) (#try.Success |state|) (do ! [_ (stm.write |state| state)] (in (#try.Success []))) (#try.Failure error) (in (#try.Failure error)))))) )))