From 4ea7563c46a07dbe1cb84547a60e9398144917ae Mon Sep 17 00:00:00 2001 From: Eduardo Julian Date: Wed, 16 Nov 2022 23:17:45 -0400 Subject: Added generic logging abstraction/machinery. --- stdlib/source/library/lux/data/color.lux | 3 +- stdlib/source/library/lux/data/color/terminal.lux | 103 ++++++++++++++++++++++ stdlib/source/library/lux/meta/type/unit.lux | 58 ++++++++---- stdlib/source/library/lux/test/unit.lux | 13 ++- stdlib/source/library/lux/world/console.lux | 3 +- stdlib/source/library/lux/world/logging.lux | 66 ++++++++++++++ 6 files changed, 222 insertions(+), 24 deletions(-) create mode 100644 stdlib/source/library/lux/data/color/terminal.lux create mode 100644 stdlib/source/library/lux/world/logging.lux (limited to 'stdlib/source/library') diff --git a/stdlib/source/library/lux/data/color.lux b/stdlib/source/library/lux/data/color.lux index a0971891a..e2bd180f3 100644 --- a/stdlib/source/library/lux/data/color.lux +++ b/stdlib/source/library/lux/data/color.lux @@ -23,7 +23,8 @@ [/ ["[0]" rgb (.only RGB)]]) -(def top (-- rgb.limit)) +(def top + (-- rgb.limit)) (def rgb_factor (|> top .int int.frac)) diff --git a/stdlib/source/library/lux/data/color/terminal.lux b/stdlib/source/library/lux/data/color/terminal.lux new file mode 100644 index 000000000..1f368de0b --- /dev/null +++ b/stdlib/source/library/lux/data/color/terminal.lux @@ -0,0 +1,103 @@ +... https://en.wikipedia.org/wiki/ANSI_escape_code#Colors +(.require + [library + [lux (.except with) + [abstract + [equivalence (.only Equivalence)]] + [data + ["[0]" text (.use "[1]#[0]" equivalence) + ["[0]" char] + ["%" \\format]]] + [math + [number + ["n" nat]]] + [meta + [macro + ["[0]" template]] + [type + ["[0]" primitive]]]]] + ["[0]" // (.only Color) + ["[0]" rgb]]) + +(primitive.def .public Command + [Text Text] + + (def .public equivalence + (Equivalence Command) + (implementation + (def (= reference it) + (let [[beforeR afterR] (primitive.representation Command reference) + [beforeI afterI] (primitive.representation Command it)] + (and (text#= beforeR beforeI) + (text#= afterR afterI)))))) + + (def command + Text + (%.format (text.of_char char.escape) "[")) + + (def .public (with command text) + (-> Command Text + Text) + (let [[before after] (primitive.representation Command command)] + (%.format before + text + after))) + + (with_template [ ] + [(def + Text + (%.format ..command (%.nat ) "m"))] + + [39 default_foreground_color] + [49 default_background_color] + ) + + (with_template [ ] + [(`` (def .public (,, (template.symbol [ "_foreground"])) + Command + (|> [(%.format ..command (%.nat ) "m") + ..default_foreground_color] + (primitive.abstraction Command)))) + + (`` (def .public (,, (template.symbol [ "_background"])) + Command + (|> [(%.format ..command (%.nat ) "m") + ..default_background_color] + (primitive.abstraction Command))))] + + [030 040 black] + [031 041 red] + [032 042 green] + [033 043 yellow] + [034 044 blue] + [035 045 magenta] + [036 046 cyan] + [037 047 white] + + [090 100 bright_black] + [091 101 bright_red] + [092 102 bright_green] + [093 103 bright_yellow] + [094 104 bright_blue] + [095 105 bright_magenta] + [096 106 bright_cyan] + [097 107 bright_white] + ) + + (with_template [ ] + [(def .public ( it) + (-> Color Command) + (let [it (//.rgb it)] + (|> [(%.format ..command + + ";" (%.nat (rgb.number (the rgb.#red it))) + ";" (%.nat (rgb.number (the rgb.#green it))) + ";" (%.nat (rgb.number (the rgb.#blue it))) + "m") + ] + (primitive.abstraction Command))))] + + ["38;2" foreground ..default_foreground_color] + ["48;2" background ..default_background_color] + ) + ) diff --git a/stdlib/source/library/lux/meta/type/unit.lux b/stdlib/source/library/lux/meta/type/unit.lux index 4aa27fbfd..e4bf7a1e9 100644 --- a/stdlib/source/library/lux/meta/type/unit.lux +++ b/stdlib/source/library/lux/meta/type/unit.lux @@ -6,6 +6,9 @@ [equivalence (.only Equivalence)] [order (.only Order)] [enum (.only Enum)]] + [data + ["[0]" text (.only) + ["%" \\format]]] [math [number ["i" int]]] @@ -21,21 +24,27 @@ Int (def .public measure - (All (_ scale unit) (-> Int (Measure scale unit))) + (All (_ scale unit) + (-> Int + (Measure scale unit))) (|>> abstraction)) (def .public number - (All (_ scale unit) (-> (Measure scale unit) Int)) + (All (_ scale unit) + (-> (Measure scale unit) + Int)) (|>> representation)) (def .public equivalence - (All (_ scale unit) (Equivalence (Measure scale unit))) + (All (_ scale unit) + (Equivalence (Measure scale unit))) (implementation (def (= reference sample) (i.= (representation reference) (representation sample))))) (def .public order - (All (_ scale unit) (Order (Measure scale unit))) + (All (_ scale unit) + (Order (Measure scale unit))) (implementation (def equivalence ..equivalence) @@ -43,7 +52,8 @@ (i.< (representation reference) (representation sample))))) (def .public enum - (All (_ scale unit) (Enum (Measure scale unit))) + (All (_ scale unit) + (Enum (Measure scale unit))) (implementation (def order ..order) (def succ (|>> representation ++ abstraction)) @@ -51,7 +61,9 @@ (with_template [ ] [(def .public ( param subject) - (All (_ scale unit) (-> (Measure scale unit) (Measure scale unit) (Measure scale unit))) + (All (_ scale unit) + (-> (Measure scale unit) (Measure scale unit) + (Measure scale unit))) (abstraction ( (representation param) (representation subject))))] @@ -61,7 +73,9 @@ (with_template [

] [(def .public ( param subject) - (All (_ scale p s) (-> (Measure scale

) (Measure scale ) (Measure scale ))) + (All (_ scale p s) + (-> (Measure scale

) (Measure scale ) + (Measure scale ))) (abstraction ( (representation param) (representation subject))))] @@ -69,16 +83,24 @@ [/ i./ p [p s] s] ) - (.type .public (Unit a) + (.type .public (Unit of) (Interface - (is (-> Int (Measure Any a)) + (is (-> (Measure Any of) + Text) + format) + (is (-> Int + (Measure Any of)) in) - (is (-> (Measure Any a) Int) + (is (-> (Measure Any of) + Int) out))) - (def .public (unit _) - (Ex (_ a) (-> Any (Unit a))) + (def .public (unit descriptor) + (Ex (_ of) + (-> Text + (Unit of))) (implementation + (def format (|>> ..number %.int (text.suffix descriptor))) (def in ..measure) (def out ..number))) ) @@ -91,9 +113,9 @@ (, it)) (, g!a)))))))) -(with_template [ ] +(with_template [ ] [(def .public - (..unit [])) + (..unit )) (.def .public (let [[module _] (symbol .._) @@ -101,8 +123,8 @@ {.#Named [module short] (..type )}))] - [gram Gram] - [meter Meter] - [litre Litre] - [second Second] + ["g" gram Gram] + ["m" meter Meter] + ["l" litre Litre] + ["s" second Second] ) diff --git a/stdlib/source/library/lux/test/unit.lux b/stdlib/source/library/lux/test/unit.lux index 86df9efd0..e8eeb0a04 100644 --- a/stdlib/source/library/lux/test/unit.lux +++ b/stdlib/source/library/lux/test/unit.lux @@ -10,6 +10,8 @@ [concurrency ["[0]" async (.only Async) (.use "[1]#[0]" monad)]]] [data + [color + ["[0]" terminal]] ["[0]" text (.only) ["%" \\format (.only format)]] [collection @@ -60,10 +62,13 @@ (-> Text Test Test) (|>> %.text context')) -(with_template [ ] +(with_template [ ] [(def (-> Text Test) - (|>> (format ) + (|>> (format "[" + (terminal.with + ) + "] ") [] async#in)) @@ -71,8 +76,8 @@ (-> Text Test) (|>> %.text ))] - ["[Failure] " tally.failure failure' failure] - ["[Success] " tally.success success' success] + ["Failure" tally.failure failure' failure terminal.red_foreground] + ["Success" tally.success success' success terminal.green_foreground] ) (def (test' message condition) diff --git a/stdlib/source/library/lux/world/console.lux b/stdlib/source/library/lux/world/console.lux index 37d8b3b07..4d3ba46d8 100644 --- a/stdlib/source/library/lux/world/console.lux +++ b/stdlib/source/library/lux/world/console.lux @@ -40,7 +40,8 @@ [read] [read_line] [write] - [close]))))) + [close] + ))))) (exception.def .public cannot_close) diff --git a/stdlib/source/library/lux/world/logging.lux b/stdlib/source/library/lux/world/logging.lux new file mode 100644 index 000000000..6f58fd134 --- /dev/null +++ b/stdlib/source/library/lux/world/logging.lux @@ -0,0 +1,66 @@ +(.require + [library + [lux (.except with) + [abstract + [monad (.only Monad do)]] + [control + ["[0]" try (.only Try)]] + [data + [color + ["[0]" terminal]] + [text + ["%" \\format]]] + [world + ["[0]" console (.only Console)] + [time + [instant (.only Instant)]]]]]) + +(type .public (Logger !) + (Interface + (is (-> Text + (! (Try Any))) + log))) + +(with_template [ ] + [(def .public ( message it) + (All (_ !) + (-> Text (Logger !) + (! (Try Any)))) + (at it log (terminal.with + (%.format message))))] + + ["[ERROR] " error terminal.red_foreground] + ["[WARNING] " warn terminal.yellow_foreground] + ["[INFO] " info terminal.white_foreground] + ["[DEBUG] " debug terminal.cyan_foreground] + ) + +(def .public (with scope it) + (All (_ !) + (-> (-> Text Text) + (-> (Logger !) (Logger !)))) + (implementation + (def log + (|>> scope + (at it log))))) + +(def .public (timed ! now it) + (All (_ !) + (-> (Monad !) (-> Any (! Instant)) + (-> (Logger !) (Logger !)))) + (implementation + (def (log message) + (do ! + [now (now [])] + (at it log (%.format (terminal.with terminal.green_foreground + (%.format "[" (%.instant now) "]")) + " " + message)))))) + +(def .public (console it) + (All (_ !) + (-> (Console !) + (Logger !))) + (implementation + (def (log message) + (console.write_line message it)))) -- cgit v1.2.3