aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/tool/compiler/meta/archive/module/document.lux
blob: 924ac967ad5fe02548f5fb8a444401db7f959107 (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
(.using
 [library
  [lux (.full)
   [abstract
    [monad (.only do)]]
   [control
    ["[0]" try (.only Try)]
    ["[0]" exception (.only exception:)]
    ["<>" parser
     [binary (.only Parser)]]]
   [data
    [collection
     ["[0]" dictionary (.only Dictionary)]]
    [format
     ["[0]" binary (.only Writer)]]]
   [type (.only sharing)
    [primitive (.full)]]]]
 [///
  ["[0]" signature (.only Signature) ("[1]#[0]" equivalence)]
  ["[0]" key (.only Key)]])

(exception: .public (invalid_signature [expected Signature
                                        actual Signature])
  (exception.report
   "Expected" (signature.description expected)
   "Actual" (signature.description actual)))

(primitive: .public (Document d)
  (Record
   [#signature Signature
    #content d])

  (def: .public (content key document)
    (All (_ d) (-> (Key d) (Document Any) (Try d)))
    (let [[document//signature document//content] (representation document)]
      (if (# signature.equivalence =
             (key.signature key)
             document//signature)
        {try.#Success (sharing [e]
                               (Key e)
                               key
                               
                               e
                               (as_expected document//content))}
        (exception.except ..invalid_signature [(key.signature key)
                                               document//signature]))))

  (def: .public (document key content)
    (All (_ d) (-> (Key d) d (Document d)))
    (abstraction [#signature (key.signature key)
                  #content content]))

  (def: .public (marked? key document)
    (All (_ d) (-> (Key d) (Document Any) (Try (Document d))))
    (do try.monad
      [_ (..content key document)]
      (in (as_expected document))))

  (def: .public signature
    (-> (Document Any) Signature)
    (|>> representation (the #signature)))

  (def: .public (writer content)
    (All (_ d) (-> (Writer d) (Writer (Document d))))
    (let [writer (all binary.and
                      signature.writer
                      content)]
      (|>> representation writer)))

  (def: .public (parser key it)
    (All (_ d) (-> (Key d) (Parser d) (Parser (Document d))))
    (do <>.monad
      [actual signature.parser
       .let [expected (key.signature key)]
       _ (if (signature#= expected actual)
           (in [])
           (<>.lifted (exception.except ..invalid_signature [expected actual])))
       it it]
      (in (abstraction [actual it]))))
  )