aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/program/aedifex/repository.lux
blob: 955e574d939a76e750494e5cc1a76218d19afa37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
... This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
... If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.

(.require
 [library
  [lux (.except)
   [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
     (of repository description))
   (def (download uri)
     (async.future (of repository download uri)))

   (def (upload uri content)
     (async.future (of 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
       (of mock the_description))
     
     (def (download uri)
       (stm.commit!
        (do [! stm.monad]
          [|state| (stm.read state)]
          (when (of 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)]
          (when (of mock on_upload uri content |state|)
            {try.#Success |state|}
            (do !
              [_ (stm.write |state| state)]
              (in {try.#Success []}))
            
            {try.#Failure error}
            (in {try.#Failure error})))))
     )))