diff options
author | Eduardo Julian | 2022-10-27 00:00:03 -0400 |
---|---|---|
committer | Eduardo Julian | 2022-10-27 00:00:03 -0400 |
commit | 54d22bc41b874d52a94a96aafca18ab3a6357edb (patch) | |
tree | f8560699f618eabbc25a621e9d62f0bc000b2125 /stdlib/source/library/lux/world/net/uri/query.lux | |
parent | 8d4c256f8b56561869c14df02db695d774c74fa6 (diff) |
Added support for aspect-oriented programming.
Diffstat (limited to 'stdlib/source/library/lux/world/net/uri/query.lux')
-rw-r--r-- | stdlib/source/library/lux/world/net/uri/query.lux | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/stdlib/source/library/lux/world/net/uri/query.lux b/stdlib/source/library/lux/world/net/uri/query.lux new file mode 100644 index 000000000..24b03512b --- /dev/null +++ b/stdlib/source/library/lux/world/net/uri/query.lux @@ -0,0 +1,106 @@ +(.require + [library + [lux (.except) + [abstract + [monad (.only do)] + [codec (.only Codec)] + [equivalence (.only Equivalence)]] + [control + ["?" parser] + ["[0]" try (.only Try)]] + [data + ["[0]" text (.only) + ["%" \\format] + ["?[1]" \\parser (.only Parser)]] + [collection + ["[0]" list (.use "[1]#[0]" functor)] + ["[0]" dictionary (.only Dictionary)]]] + [math + [number + ["[0]" nat]]] + [world + [net + ["[0]" uri + ["[1]" encoding]]]]]]) + +(type .public Query + (Dictionary Text Text)) + +(def .public empty + Query + (dictionary.empty text.hash)) + +(def .public equivalence + (Equivalence Query) + (dictionary.equivalence text.equivalence)) + +(def component + (Parser Text) + (?.rec + (function (_ component) + (do [! ?.monad] + [head (?text.some (?text.none_of "+%&;"))] + (all ?.either + (?.after (?.either ?text.end + (?text.this "&")) + (in head)) + (do ! + [_ (?text.this "+") + tail component] + (in (%.format head " " tail))) + (do ! + [_ (?text.this "%") + code (|> (?text.exactly 2 ?text.hexadecimal) + (?.codec nat.hex) + (at ! each text.of_char)) + tail component] + (in (%.format head code tail)))))))) + +(def separators + "&;") + +(def assignment + "=") + +(def invalid + (%.format "=" "&;")) + +(def (form query) + (-> Query (Parser Query)) + (all ?.either + (do ?.monad + [_ ?text.end] + (in query)) + (do [! ?.monad] + [key (?text.some (?text.none_of ..invalid)) + key (?text.local key ..component) + key (?.lifted (uri.decoded key))] + (?.either (do ! + [_ (?text.this ..assignment) + value ..component + value (?.lifted (uri.decoded value))] + (form (dictionary.has key value query))) + (do ! + [_ (all ?.or + (?text.one_of ..separators) + ?text.end)] + (form (dictionary.has key "" query))))) + ... if invalid form data, just stop parsing... + (at ?.monad in query))) + +(def format + (%.Format Query) + (|>> dictionary.entries + (list#each (function (_ [key value]) + (%.format (uri.encoded key) "=" (uri.encoded value)))) + (text.interposed "&"))) + +(def query + (-> Text (Try Query)) + (?text.result (..form ..empty))) + +(def .public codec + (Codec Text Query) + (implementation + (def encoded ..format) + (def decoded ..query))) |