aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/data/text/format.lux
blob: 8a5509a8f4b4b177919651632394f534712e815e (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
(.module:
  [library
   [lux {"-" list nat int rev type}
    [abstract
     [monad {"+" do}]
     [functor
      ["[0]" contravariant]]]
    [control
     ["<>" parser
      ["<[0]>" code {"+" Parser}]]]
    [data
     ["[0]" bit]
     ["[0]" text]
     [format
      ["[0]" xml]
      ["[0]" json]]
     [collection
      ["[0]" list ("[1]#[0]" monad)]]]
    ["[0]" time
     ["[0]" instant]
     ["[0]" duration]
     ["[0]" date]
     ["[0]" day]
     ["[0]" month]]
    [math
     ["[0]" modular]
     [number
      ["[0]" nat]
      ["[0]" int]
      ["[0]" rev]
      ["[0]" frac]
      ["[0]" ratio]]]
    [macro
     [syntax {"+" syntax:}]
     ["[0]" code]
     ["[0]" template]]
    [meta
     ["[0]" location]
     ["[0]" symbol]]
    ["[0]" type]]])

(type: .public (Format a)
  (-> a Text))

(implementation: .public functor
  (contravariant.Functor Format)
  
  (def: (each f fb)
    (|>> f fb)))

(syntax: .public (format [fragments (<>.many <code>.any)])
  (in (.list (` ($_ "lux text concat" (~+ fragments))))))

(template [<name> <type> <formatter>]
  [(def: .public <name>
     (Format <type>)
     <formatter>)]

  [bit      Bit               (# bit.codec encoded)]
  [nat      Nat               (# nat.decimal encoded)]
  [int      Int               (# int.decimal encoded)]
  [rev      Rev               (# rev.decimal encoded)]
  [frac     Frac              (# frac.decimal encoded)]
  [text     Text              text.format]
  
  [ratio    ratio.Ratio       (# ratio.codec encoded)]
  [symbol   Symbol            (# symbol.codec encoded)]
  [location Location          location.format]
  [code     Code              code.format]
  [type     Type              type.format]
  
  [instant  instant.Instant   (# instant.codec encoded)]
  [duration duration.Duration (# duration.codec encoded)]
  [date     date.Date         (# date.codec encoded)]
  [time     time.Time         (# time.codec encoded)]
  [day      day.Day           (# day.codec encoded)]
  [month    month.Month       (# month.codec encoded)]
  
  [xml      xml.XML           (# xml.codec encoded)]
  [json     json.JSON         (# json.codec encoded)]
  )

(template [<type> <format>,<codec>]
  [(`` (template [<format> <codec>]
         [(def: .public <format>
            (Format <type>)
            (# <codec> encoded))]

         (~~ (template.spliced <format>,<codec>))))]

  [Nat
   [[nat/2 nat.binary]
    [nat/8 nat.octal]
    [nat/10 nat.decimal]
    [nat/16 nat.hex]]]
  [Int
   [[int/2 int.binary]
    [int/8 int.octal]
    [int/10 int.decimal]
    [int/16 int.hex]]]
  [Rev
   [[rev/2 rev.binary]
    [rev/8 rev.octal]
    [rev/10 rev.decimal]
    [rev/16 rev.hex]]]
  [Frac
   [[frac/2 frac.binary]
    [frac/8 frac.octal]
    [frac/10 frac.decimal]
    [frac/16 frac.hex]]]
  )

(def: .public (mod modular)
  (All (_ m) (Format (modular.Mod m)))
  (let [codec (modular.codec (modular.modulus modular))]
    (# codec encoded modular)))

(def: .public (list formatter)
  (All (_ a) (-> (Format a) (Format (List a))))
  (|>> (list#each (|>> formatter (format " ")))
       text.together
       (text.enclosed ["(list" ")"])))

(def: .public (maybe format)
  (All (_ a) (-> (Format a) (Format (Maybe a))))
  (function (_ value)
    (case value
      {.#None}
      "{.#None}"

      {.#Some value}
      (..format "{.#Some " (format value) "}"))))