(.using [library [lux "*" [abstract [monad (.only do)]] [control [io (.only IO)] ["[0]" try (.only Try)] [concurrency ["[0]" async (.only Async)] ["[0]" stm]]] [data [binary (.only Binary)]] [world [net [uri (.only URI)]]]]]) (type: .public (Repository !) (Interface (is Text description) (is (-> URI (! (Try Binary))) download) (is (-> 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 (is Text the_description) (is (-> URI s (Try [s Binary])) on_download) (is (-> 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}))))) )))