aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/program/aedifex/repository.lux
blob: bd1d23d3eaaac26c85eddaf94a7fbd6540d956e6 (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
(.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
     (at repository description))
   (def (download uri)
     (async.future (at repository download uri)))

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